Swift 中无法理解的错误
Incomprehensible errors in Swift
这个有效:
func averageOf(numbers: Int...) -> Float {
var sum = 0
for number in numbers {
sum += number
}
return Float(sum) / Float(numbers.count)
}
averageOf() // (not a number)
averageOf(42, 597, 12) // (217.0)
但事实并非如此:
func averageOf(numbers: Int...) -> Float {
var sum = 0
for number in numbers {
sum += number
}
return Float(sum / numbers.count)
}
averageOf()
averageOf(42, 597, 12)
它在 }
行给我这个错误:
Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
我偶然发现 another question 具有相同的第一段和第二段代码,而作者显然没有得到相同的错误。
让我们删除该演员表:
func averageOf(numbers: Int...) -> Float {
var sum = 0
for number in numbers {
sum += number
}
return sum / numbers.count
}
averageOf()
averageOf(42, 597, 12)
它给了我这个错误,在除号上:
Cannot invoke '/' with an argument list of type '(@lvalue Int, Int)'
如果我然后将函数的 return 类型更改为 Int
:
func averageOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum / numbers.count
}
averageOf()
averageOf(42, 597, 12)
我得到了同样的 EXC_BAD_INSTRUCTION 错误。
如果我只投numbers.count
:
func averageOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum / Float(numbers.count)
}
averageOf()
averageOf(42, 597, 12)
我在除号上遇到这个错误:
Cannot invoke 'init' with an argument list of type '(@lvalue Int, $T5)'
如果我将 return 类型改回 Float
,我也会收到此错误。
所有这些对我来说毫无意义。是 Xcode 邮寄,还是我漏掉了一些微妙的东西?
发生此错误是因为您的函数调用 averageOf()
。
如果您未传递任何值,可变参数 numbers
将创建一个空数组。
它是 count
属性 因此 returns 0
。而且你不能除以 0
。
这也是为什么它说 BAD_INSTRUCTION
.
的原因
如果您从第二个代码示例中删除 averageOf()
,它会起作用。
如前所述,第二个示例中的问题是由于不带参数调用 averageOf()
,导致被零除。但是,第一个 averageOf()
仍然没有参数,为什么?让我再补充一些细节。
在您报告的第一种情况下,您没有收到任何错误并且 averageOf()
有效,因为您在除法之前将两个 Int
操作数转换为 Float
。
在 Float
数字的世界中,0.0 只是 0 的近似值。如果你在 Playground 中尝试 0.0 / 0.0
,你不会因此得到错误,相反,输出将是 not a number
.
然而,在第二种情况下,您试图在转换为 Float
之前将 0 除以 0。所以,我们在进行除法的时候,还是在Int
个数的境界。由于除以零(此处不涉及近似值),结果是错误的。如果你在 Playground 中尝试 0 / 0
,你会得到一个错误。
Int
与 Float
行为无法解释的所有其他情况,是由于 Swift 要求您在类型之间显式转换,即使另一种语言会让您隐式转换操作数。
这个有效:
func averageOf(numbers: Int...) -> Float {
var sum = 0
for number in numbers {
sum += number
}
return Float(sum) / Float(numbers.count)
}
averageOf() // (not a number)
averageOf(42, 597, 12) // (217.0)
但事实并非如此:
func averageOf(numbers: Int...) -> Float {
var sum = 0
for number in numbers {
sum += number
}
return Float(sum / numbers.count)
}
averageOf()
averageOf(42, 597, 12)
它在 }
行给我这个错误:
Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
我偶然发现 another question 具有相同的第一段和第二段代码,而作者显然没有得到相同的错误。
让我们删除该演员表:
func averageOf(numbers: Int...) -> Float {
var sum = 0
for number in numbers {
sum += number
}
return sum / numbers.count
}
averageOf()
averageOf(42, 597, 12)
它给了我这个错误,在除号上:
Cannot invoke '/' with an argument list of type '(@lvalue Int, Int)'
如果我然后将函数的 return 类型更改为 Int
:
func averageOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum / numbers.count
}
averageOf()
averageOf(42, 597, 12)
我得到了同样的 EXC_BAD_INSTRUCTION 错误。
如果我只投numbers.count
:
func averageOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum / Float(numbers.count)
}
averageOf()
averageOf(42, 597, 12)
我在除号上遇到这个错误:
Cannot invoke 'init' with an argument list of type '(@lvalue Int, $T5)'
如果我将 return 类型改回 Float
,我也会收到此错误。
所有这些对我来说毫无意义。是 Xcode 邮寄,还是我漏掉了一些微妙的东西?
发生此错误是因为您的函数调用 averageOf()
。
如果您未传递任何值,可变参数 numbers
将创建一个空数组。
它是 count
属性 因此 returns 0
。而且你不能除以 0
。
这也是为什么它说 BAD_INSTRUCTION
.
如果您从第二个代码示例中删除 averageOf()
,它会起作用。
如前所述,第二个示例中的问题是由于不带参数调用 averageOf()
,导致被零除。但是,第一个 averageOf()
仍然没有参数,为什么?让我再补充一些细节。
在您报告的第一种情况下,您没有收到任何错误并且 averageOf()
有效,因为您在除法之前将两个 Int
操作数转换为 Float
。
在 Float
数字的世界中,0.0 只是 0 的近似值。如果你在 Playground 中尝试 0.0 / 0.0
,你不会因此得到错误,相反,输出将是 not a number
.
然而,在第二种情况下,您试图在转换为 Float
之前将 0 除以 0。所以,我们在进行除法的时候,还是在Int
个数的境界。由于除以零(此处不涉及近似值),结果是错误的。如果你在 Playground 中尝试 0 / 0
,你会得到一个错误。
Int
与 Float
行为无法解释的所有其他情况,是由于 Swift 要求您在类型之间显式转换,即使另一种语言会让您隐式转换操作数。