Swift 中初始化的三元运算符

Ternary Operators For Initialisation In Swift

来自 How to customize ternary operators in Swift 我知道可以使用两个二元运算符创建自定义三元运算符,我的问题是:

有什么方法可以使用它来初始化 类 或结构?

假设我有一个 LinearEquation。一切正常,但初始化实例感觉不太自然。目前它是这样工作的:

struct LinearEquation {
    var m: Double
    var c: Double

    func of(x: Double) -> Double {
        return m * x + c
    }
}

let f = LinearEquation(m: 2, c: 1)
f.of(2) // returns 5

有没有一种方法可以通过编写 let f = m * x + c 来创建 LinearEquation?如果直线经过原点,是否也可以省略 + c

(我已经在下面给出了答案,但我想知道是否有人对我答案末尾所述的原因有任何其他建议)

我不会在所有情况下都使用该语法,因为还不完全清楚 f 是什么类型。你可以改写:

let f: LinearEquation = m * x + c

它不是很简洁,但是它使意图更加清晰。无论如何,进入我的回答!

首先,看例子:如果你分解语句f = m * x + cm * x + c到return是有意义的LinearEquation 然后分配给 f。然后问题变成重载 *+ 以创建 LinearEquation:

其次, x,在这种情况下,实际上并没有在创建LinearEquation时提供任何信息;它只是稍后将使用的 x 值的占位符。因此,我将在全局范围内声明 x,如下所示:

func x() {} // Yup, does nothing!

第三,您需要考虑计算运算符的顺序。因此 x * m 将首先被计算, + c 将被第二个计算。这意味着 x * m 可以 return 没有 y 截距的 LinearEquation。然后 + 运算符可以采用 LinearEquation,添加截距和 return return 完整的 LinearEquation。以下是运算符:

// lhs is where you pass x, defined earlier.
func * (lhs: () -> Void, rhs: Double) -> LinearEquation {
    return LinearEquation(m: rhs, c: 0.0)
}

func + (var lhs: LinearEquation, rhs: Double) -> LinearEquation {
    lhs.c = rhs
    return lhs
}

最后, 现在您可以像这样创建 LinearEquation

let f = x * 2 + 1
f.of(2) // returns 5

或者如果它经过原点:

let f = x * 2
f.of(2) // returns 4

我能想到的一个主要问题是现在无法使用 x 作为变量。因此,如果有人有更好的解决方案,我们会很高兴听到。

我会选择稍微不同的方法。有了您的解决方案,您 得到意想不到的结果:

let f1 = x * 2 + (1 + 2)
println(f1.of(1)) // 5.0 (correct)

let f2 = x * 2 + 1 + 2
println(f2.of(1)) // 4.0 (What ??)

let f3 = { println("foo") } * 2

编译没有意义。

我会将线性函数 "x" 定义为静态成员 (和 mc 作为 常量 属性):

struct LinearEquation {
    let m: Double
    let c: Double

    func of(x: Double) -> Double {
        return m * x + c
    }

    static let X = LinearEquation(m: 1.0, c: 0.0)
}

加法和乘法为

func * (lhs: LinearEquation, rhs: Double) -> LinearEquation {
    return LinearEquation(m: lhs.m * rhs, c: lhs.c * rhs)
}

func + (lhs: LinearEquation, rhs: Double) -> LinearEquation {
    return LinearEquation(m: lhs.m, c: lhs.c + rhs)
}

然后

let f1 = LinearEquation.X * 2 + 1 + 2
println(f1.of(1)) // 5.0

按预期工作。并与

extension LinearEquation : FloatLiteralConvertible {
    init(floatLiteral value: Double) {
        self = LinearEquation(m: 0.0, c: value)
    }
}

你可以简单地定义一个常数函数

let f2 : LinearEquation = 2.0
println(f2.of(3)) // 2.0