【问题标题】:Ternary Operators For Initialisation In SwiftSwift 中用于初始化的三元运算符
【发布时间】:2015-07-11 08:21:11
【问题描述】:

来自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

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

【问题讨论】:

    标签: swift operator-keyword ternary


    【解决方案1】:

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

    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
    

    【讨论】:

    • 根据我的回答,我没有考虑过您会得到什么其他无意义的结果,所以感谢您指出这一点!不过你的作品很完美! FloatLiteralConvertible 的好主意!
    【解决方案2】:

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

    let f: LinearEquation = m * x + c
    

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

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

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

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

    第三,您需要考虑运算符的计算顺序。因此x * m 将首先被评估,+ c 将被评估其次。这意味着 x * m 可以返回没有 y 截距的 LinearEquation。然后+ 运算符可以取LinearEquation,添加截距并返回完整的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 用作变量。因此,如果有人有更好的解决方案,那就太好了。

    【讨论】:

      猜你喜欢
      • 2013-07-27
      • 2023-01-02
      • 2021-07-03
      • 2010-12-20
      • 2023-03-27
      • 2018-07-02
      • 2012-07-14
      • 2013-03-30
      • 1970-01-01
      相关资源
      最近更新 更多