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 + c
,m * 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" 定义为静态成员
(和 m
、c
作为 常量 属性):
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
来自 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 + c
,m * 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" 定义为静态成员
(和 m
、c
作为 常量 属性):
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