【问题标题】:Trying to implement ?.let pattern in Swift, is it even possible?尝试在 Swift 中实现 ?.let 模式,有可能吗?
【发布时间】: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上写个扩展就行了,差别不大。

标签: swift kotlin


【解决方案1】:

其实我觉得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 周围的封闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 2011-09-15
    相关资源
    最近更新 更多