我一直在Swift和Kotlin之间来回移植代码。受this answer的启发,我一直使用?.let { } ?: run {}
来代替我在Swift中使用if let ... { } else {}
的许多地方。
我真的很喜欢Kotlin的表情。在我看来,它比关键字特定的if let
混合更笼统。因此,出于平价考虑-或至少为了尝试愚蠢的实验学习-我认为我会尝试在Swift中实现let
构造。
因为let
是Swift中的关键字,所以我立即发现我需要加反引号或使用其他名称,例如cull
。这导致了以下无法编译的代码:
extension Any {
func cull<R>(block:(Self) -> R) -> R {
return block(self)
}
}
给了我学徒级别的技能,可能有很多问题。但最重要的是,我得知我无法扩展Any(即explained in better detail here)。
因此任何内容都无法扩展。我可以使用其他任何语言构造来使之实现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
这如我所愿。但是我不想扩展系统中的每个非标称类型来使其工作。我只想全局定义它。如果可能的话。
答案 0 :(得分:2)
实际上,我认为Optional
中已经存在这种方法。尽管这仅适用于可选选项,但至少可以解决您缺少?.let
的问题。该方法称为map
。
let optional: String? = "hello"
optional.map { print($0) } // prints hello
// note how I did not unwrap the optional. I called "map" directly on the optional, not the wrapped "String".
您可以将值map
转换为另一个值,或Void
,就像我上面所做的那样。
我认为您不能对所有内容都使用let
方法。
是的,在查看了Kotlin中的“非本地收益”之后,我认为您不能在Swift中做同样的事情。那些花括号的东西是“封闭的”。它们是“封闭的”,因此您不能return
在内部封闭中context
封闭封闭。