尝试在Swift中实现?.let模式,是否有可能?

时间:2018-08-05 00:34:12

标签: swift kotlin

我一直在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

这如我所愿。但是我不想扩展系统中的每个非标称类型来使其工作。我只想全局定义它。如果可能的话。

1 个答案:

答案 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方法。

如果要在闭包内部返回可选内容,也可以使用

flatMap

是的,在查看了Kotlin中的“非本地收益”之后,我认为您不能在Swift中做同样的事情。那些花括号的东西是“封闭的”。它们是“封闭的”,因此您不能return在内部封闭中context封闭封闭。