Swift 的 int 字面值到浮点数的推理是如何工作的?
How does Swift's int literal to float inference work?
Swift 可以将 int 文字推断为双精度或浮点数
let x: Float = 3
它甚至适用于算术。它会在进行数学计算之前转换所有内容,所以这也是 3:
let y: Float = 5/2 + 0.5
但这方面的实际规则是什么?有歧义的情况,例如如果推断是针对一个参数:
func foobar(_ x: Int) -> Int {
return x
}
func foobar(_ x: Float) -> Float {
return y
}
foobar(1/2)
在这种情况下,它会将其推断为 int 和 returns 0,但如果删除第一个函数,它会切换为 float 和 returns 0.5。
规则是什么?它在哪里记录?
更烦人的是 Swift 可以 将其推断为浮点数但
func foobar(_ x: Float) -> Float {
return x
}
let x = 1/2
foobar(x) // Cannot convert value of type 'Int' to expected argument type 'Float'
文字没有这样的类型。文档说,
If there isn’t suitable type information available, Swift infers that the
literal’s type is one of the default literal
types defined in the Swift standard library. The default types are Int
for integer literals, Double for floating-point literals, String for
string literals, and Bool for Boolean literals.
因此,除非您的论点明确表示 Int
以外的任何内容,否则它会将整数文字推断为 Int
。
请参阅此以获取更多信息,Lexical Structure - Literals。
默认情况下,传入 1/2
作为您的参数,您正在对两个 整数 执行计算,这将计算出 类型的结果Integer 因此第一个函数被使用。
要有一个 Float,一个或所有参数必须是 Float
类型,所以 1.0/2
或 1/2.0
或1.0/2.0
。这将导致第二个函数改为 运行。
在let x = 1/2
中,x被推断为Int
类型,因为1
和2
都是Int[=32=类型].
如果没有指明,Swift 将不会尝试推断 Float。
这里有两个 Swift 行为在起作用:
- Swift 可以将 int literal 推断为 type float 如果需要(或 double)
- 每个文字都有一个默认类型,在推理失败时使用。 int 文字的类型是
Int
只有一个函数,适用规则 1。它发现需要一个浮点数,所以它将除法推断为浮点数除法,并将 int 文字推断为浮点数:
func foobar(_ x: Float) -> Float {
return y
}
foobar(1/2) // 0.5
如果重载函数,规则 1 将不再有效。该类型现在不明确,因此它回退到默认类型 Int
,幸运的是它与定义之一匹配:
func foobar(_ x: Int) -> Int {
return x
}
func foobar(_ x: Float) -> Float {
return y
}
foobar(1/2) // 0
看看如果你让默认值不再有效会发生什么。两条规则都不适用,因此您会收到错误消息:
func foobar(_ x: Double) -> Double {
return x
}
func foobar(_ x: Float) -> Float {
return y
}
foobar(1/2) // Ambiguous use of operator '/'
Swift 可以将 int 文字推断为双精度或浮点数
let x: Float = 3
它甚至适用于算术。它会在进行数学计算之前转换所有内容,所以这也是 3:
let y: Float = 5/2 + 0.5
但这方面的实际规则是什么?有歧义的情况,例如如果推断是针对一个参数:
func foobar(_ x: Int) -> Int {
return x
}
func foobar(_ x: Float) -> Float {
return y
}
foobar(1/2)
在这种情况下,它会将其推断为 int 和 returns 0,但如果删除第一个函数,它会切换为 float 和 returns 0.5。
规则是什么?它在哪里记录?
更烦人的是 Swift 可以 将其推断为浮点数但
func foobar(_ x: Float) -> Float {
return x
}
let x = 1/2
foobar(x) // Cannot convert value of type 'Int' to expected argument type 'Float'
文字没有这样的类型。文档说,
If there isn’t suitable type information available, Swift infers that the literal’s type is one of the default literal types defined in the Swift standard library. The default types are Int for integer literals, Double for floating-point literals, String for string literals, and Bool for Boolean literals.
因此,除非您的论点明确表示 Int
以外的任何内容,否则它会将整数文字推断为 Int
。
请参阅此以获取更多信息,Lexical Structure - Literals。
默认情况下,传入 1/2
作为您的参数,您正在对两个 整数 执行计算,这将计算出 类型的结果Integer 因此第一个函数被使用。
要有一个 Float,一个或所有参数必须是 Float
类型,所以 1.0/2
或 1/2.0
或1.0/2.0
。这将导致第二个函数改为 运行。
在let x = 1/2
中,x被推断为Int
类型,因为1
和2
都是Int[=32=类型].
Swift 将不会尝试推断 Float。
这里有两个 Swift 行为在起作用:
- Swift 可以将 int literal 推断为 type float 如果需要(或 double)
- 每个文字都有一个默认类型,在推理失败时使用。 int 文字的类型是
Int
只有一个函数,适用规则 1。它发现需要一个浮点数,所以它将除法推断为浮点数除法,并将 int 文字推断为浮点数:
func foobar(_ x: Float) -> Float {
return y
}
foobar(1/2) // 0.5
如果重载函数,规则 1 将不再有效。该类型现在不明确,因此它回退到默认类型 Int
,幸运的是它与定义之一匹配:
func foobar(_ x: Int) -> Int {
return x
}
func foobar(_ x: Float) -> Float {
return y
}
foobar(1/2) // 0
看看如果你让默认值不再有效会发生什么。两条规则都不适用,因此您会收到错误消息:
func foobar(_ x: Double) -> Double {
return x
}
func foobar(_ x: Float) -> Float {
return y
}
foobar(1/2) // Ambiguous use of operator '/'