我在Swift中有以下代码:
func foo()
{
let name = "Hello World"
if name is String
{
}
else
{
}
}
I get the error: 'is' test is always true
我知道这总是如此!但为什么这是一个错误?
答案 0 :(得分:4)
Swift通过类型推断编译你的声明,如下所示:
let name: String = "Hello World"
if name is String { ...
你无法根据声明的类型测试变量的类型,因为它总是正确的,并且这个事实在编译时很明显。在这种情况下,你知道确保name
是String
。 Swift的静态类型意味着您永远不需要进行此测试。您始终可以假设String
类型的变量是String
。
要使用is
,var的类型必须是可转换的,但与您要比较的类型不同。因此,如果name
是一个可能是String
的模糊类型,或者可能是完全不同的东西,那么将编译。然后测试真的有意义。
let name: AnyObject = "Hello World"
if name is String {
println("name is a string")
} else {
println("name is NOT a string :(")
}
有关何时可以is
以及何时不可以的更多示例。
// Good
// AnyObject can be casted to String
let name: AnyObject = "Hello World"
if name is String {}
// Also good
// UInt32 can be casted to Int
let num: UInt32 = 123
if num is Int {}
// error: 'String' is not a subtype of 'Int'
// Int cannot be casted to String, this will NEVER be true
let name: Int = 123
if name is String {}
// error: 'is' test is always true
// String will always be string, this will ALWAYS be true
let name: String = "Hello"
if name is String {}
答案 1 :(得分:3)
这是一个错误,因为Swift尽最大努力阻止你做无用的事情。斯威夫特认为,由于这次测试总是如此,你必须有意做其他事情。
答案 2 :(得分:1)
swift中的变量是(非常)强类型的。如果你写这样的东西,很可能你在代码中做错了。
我很欣赏编译器将其输出为错误 - 否则我可能会在某些条件下执行else分支。
数据类型和结构不支持继承,因此如果您声明String
变量,则它不能是其他任何内容(除Any
和AnyObject
之外,它们是协议)。
如果声明一个字符串变量:
var test: String = "test"
它永远不会是其他任何东西,所以这总是失败:
if test is Int { // < 'Int' is not a subtype of 'String'
...
}
测试字符串是否是字符串是没有意义的,因此编译器认为它是一个错误,尽管它可能更像是一个警告,因为代码在语法和语义上都是正确的。
顺便检查Any
和AnyObject
的数据类型或结构会产生相同的错误,因此我认为这对于它们实现的任何协议都是有效的。