评估Swift中的对象类型

时间:2014-09-08 17:14:19

标签: swift

我在Swift中有以下代码:

 func foo()
    {
        let name = "Hello World"

        if name is String
        {

        }
        else
        {

        }
    }


I get the error: 'is' test is always true 

我知道这总是如此!但为什么这是一个错误?

3 个答案:

答案 0 :(得分:4)

Swift通过类型推断编译你的声明,如下所示:

let name: String = "Hello World"
if name is String { ...

你无法根据声明的类型测试变量的类型,因为它总是正确的,并且这个事实在编译时很明显。在这种情况下,你知道确保nameString。 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变量,则它不能是其他任何内容(除AnyAnyObject之外,它们是协议)。

如果声明一个字符串变量:

var test: String = "test"

它永远不会是其他任何东西,所以这总是失败:

if test is Int { // < 'Int' is not a subtype of 'String'
    ...
}

测试字符串是否是字符串是没有意义的,因此编译器认为它是一个错误,尽管它可能更像是一个警告,因为代码在语法和语义上都是正确的。

顺便检查AnyAnyObject的数据类型或结构会产生相同的错误,因此我认为这对于它们实现的任何协议都是有效的。