对应 swift 当中的文档 Documentation
其他例子 Using dot syntax for static properties and initializers | Swift by Sundell
Swift 中的案例
最近在 Swift 中使用标签参数比较多, 跟 MoonBit 做一下参考, 觉得这个功能挺方便的, 特别集中在数据结构初始化的场景,
比如:
public extension RepeatMode {
static var never: RepeatMode {
return .times(0) // <--- 这里 times 方法根据上下文推断得到所属类型, 于是可以省略类型
}
static var once: RepeatMode {
return .times(1)
}
}
另一个例子,
rootEntity.components.set(
CollisionComponent(
shapes: [
.generateBox( // <- 这里 shapes 成员类型为 [ShapeResource],
// 数组内通过推断获得 ShapeResource.generateBox 静态方法
width: bounds.extents.x * 4,
height: bounds.extents.y * 4,
depth: bounds.extents.z * 4)
]
)
)
这个例子中 Implicit Member Expression 跟标签函数一起用, 就显得更加灵活,
extension ImageFilter {
static var dramatic: Self {
ImageFilter(
name: "Dramatic",
icon: .drama,
transforms: [
.portrait(withZoomMultipler: 2.1), // <-- 这里
.contrastBoost,
.grayScale(withBrightness: .dark)
]
)
}
}
或者搭配标签参数创建颜色,
UIColor(
red:.random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1),
alpha: 1
)
MoonBit 中假想案例
对应到 MoonBit 比如在定义 CSS 样式的时候(这个我遇到比较多), 在 style 的位置推断到类型是 CSSProperties
,
div(style= ... , [])
那么 .init()
方法配合标签参数就可以简写或者说通过 .
打开补全菜单直接找到初始化的方法, 从而减少手动引入额外一个方法来提供 labelled arguments,
div(style=.init(color="red", font_size=13) , [])
这个写法可以用在更多可以推断类型的场景, 比如, 变量初始化,
let xs: Array[string] = .with_capacity(8)
let ys: @list.T[Int] = .from_array([1,2,3,4])
比如 Option
类型的数据,
fn display(x: Option[String]) { ... }
display(.some("demo"))
// 这个写法可能体现不出优势
// display(Some("demo"))
总体上说, 对于 UI 这一类需要撰写嵌套的 DSL, 反复初始化多种结构, 配置参数, 的场景, 我觉得帮助会比较明显. 特别是类似 Swift 这样 IDE 中使用 .
开始打开菜单就能探索方法的场景.
另外, 这个写法应该有一些限制, 要求推断上下文得到的类型比如 S
, 跟调用的方法返回的类型, 应该是一致的, 也就是 Self
, 因此可以作为 initializer 而简写,
fn S::f(a: A, b: B) -> Self { ... }
我觉得这个功能现在已有的 enum contructor 自动推断也是不错的补充, enum constructor 已经很灵活但传递的参数直接用于构造类型, 可以用这个语法封装逻辑来做更复杂的初始化功能.