【发布时间】:2018-08-05 00:34:12
【问题描述】:
我一直在 Swift 和 Kotlin 之间来回移植代码。受this answer 的启发,我一直使用?.let { } ?: run {} 作为我在Swift 中使用if let ... { } else {} 的许多地方的替代品。
不过,我真的很喜欢 Kotlin 表达式。在我看来,它比特定于关键字的if let concoction 更通用。因此,为了平价——或者至少为了通过尝试愚蠢的实验来学习——我想我会尝试在 Swift 中实现 let 构造。
因为let 是 Swift 中的关键字,我马上发现我需要使用反引号,或者使用其他名称,例如 cull。这导致了这个无法编译的代码:
extension Any {
func cull<R>(block:(Self) -> R) -> R {
return block(self)
}
}
以我学徒级别的技能,可能有很多问题。但最重要的是,我被告知无法扩展 Any(即explained in better detail here)。
所以 Any 不能扩展。我可以使用任何其他语言结构来实现它,以便我可以实现像 Kotlin 的let 这样的东西?基本上:
<expression>.foo { <expressionResult> in ... }
作为一个额外的问题,我认为即使有一种方法(我希望有这样我可以学习),它也不一样,因为 Kotlin 可以用于控制流,因为我可以从 Kotlin 中进行非本地返回,但不能从 Swift 闭包中返回。这也是正确的吗?
澄清
基本上,我可以为指定类型实现 Kotlin let 模式:
protocol Cullable {}
extension Cullable {
func cull<R>(_ block:(Self) -> R) -> R {
return block(self)
}
}
extension Int:Cullable { }
42.cull { thing in print(thing) } // this will print 42
这可以按我的意愿工作。但我不想扩展系统中的每一个非标称类型以使其工作。我只是想以某种方式在全球范围内定义它。如果可能的话。
【问题讨论】:
-
这是不可能的,因为没有办法让“foo”部分被捕获并传递给你编造的任何函数。
if let是语言功能,而不是库功能 -
见
CLARIFICATION@Alexander。 -
哦,我明白了。在
Optional上写个扩展就行了,差别不大。