试图实施?让模式在SWIFT中出现,这有可能吗?

hm2xizp9  于 2022-10-23  发布在  Swift
关注(0)|答案(2)|浏览(175)

我一直在Swift和Kotlin之间来回移植代码。受this answer的启发,我一直在使用?.let { } ?: run {}作为我在Swift中使用的许多地方的替代品。
不过,我真的喜欢上了Kotlin的表达方式。在我看来,它比关键字特定的if let组合更通用。因此,为了对等--或者至少是为了通过尝试愚蠢的实验来学习--我想我应该尝试在Swift中实现let结构。
因为let是SWIFT中的一个关键字,我立刻发现我需要加上反号,或者使用一个不同的名称,比如cull。这导致了无法编译的代码:

extension Any {
    func cull<R>(block:(Self) -> R) -> R {
        return block(self)
    }
}

以我的学徒水平,可能有很多问题。但最重要的是,我被告知我不能扩展任何(这在这里有更详细的解释)。
所以任何都不能扩展。有没有其他语言构造可以用来实现它,以便实现像Kotlin的let那样的东西?基本上:

<expression>.foo { <expressionResult> in ... }

作为一个额外的/附带的问题,我认为即使有一种方法(我确实希望有这样的方法,这样我就可以学习),它也不会一样,因为Kotlin One可以用于控制流,因为我可以从Kotlin One进行非本地返回,但不能从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

这就是我想要的效果。但我不想为了使其正常工作而扩展系统中的每一个非名义类型。我只是想在全球范围内给它下个定义。如果可能的话。

e1xvtsh3

e1xvtsh31#

实际上,我认为在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做同样的事情。那些花括号的东西就是“闭合”。它们是“闭合的”,所以你不能把周围的闭包放在一个内部闭包中。

6pp0gazn

6pp0gazn2#

遗憾的是,不能将map与某些数据类型一起使用。或者,可以使用Optional类型的扩展。我正在使用这个解决方案:

extension Optional {
    @discardableResult
    func `let`<T>(block:(T) -> Self) -> Self {
        guard let self = self as? T else { return self }
        return block(self)
    }
}

示例:

var x: Int? = 5
var y: Int?
var xx: Int
var yy: Int

xx = x.let { $0 * 10 } ?? 1
yy = y.let { $0 * 10 } ?? 2
print("Result: \(xx), \(yy)")

打印“结果:50,2”

optional.let { 
    /* optional is not nil */ 
} ?? { 
    /* optional is nil */ 
}()

相关问题