类型安全和类型推断有什么区别?

What is the difference between Type Safety and Type Inference?

它们有什么不同?我有点困惑,因为它们似乎是相似的概念。

了解它们如何帮助优化编译时间?

来自Swift自己的documentation:

类型安全

Swift 是一种类型安全的语言。类型安全的语言鼓励您清楚代码可以使用的值类型。 如果您的部分代码需要 String,则不能错误地将 Int 传递给它。

var welcomeMessage: String
welcomeMessage = 22 // this would create an error because you  
//already specified that it's going to be a String

类型推断

如果您没有指定您需要的值的类型,Swift会使用类型推断来计算出合适的类型。类型推断使编译器 能够在编译您的代码时自动推断出特定表达式的类型 ,只需检查您提供的值即可。

var meaningOfLife = 42 // meaningOfLife is inferred to be of type Int
meaningOfLife = 55 // it Works, because 55 is an Int

类型安全和类型推断相结合

var meaningOfLife = 42 // 'Type inference' happened here, we didn't specify that this an Int, the compiler itself found out.
meaningOfLife = 55 // it Works, because 55 is an Int
meaningOfLife = "SomeString" // Because of 'Type Safety' ability you will get an 
//error message: 'cannot assign value of type 'String' to type 'Int'' 

具有关联类型的协议的棘手示例:

想象一下下面的协议

protocol Identifiable {
    associatedtype ID
    var id: ID { get set }

}

你会这样采用它:

struct Person: Identifiable {
    typealias ID = String
    var id: String
}

不过你也可以这样领养:

struct Website: Identifiable {
    var id: URL
}

您可以删除 typealias。编译器仍会推断类型。

有关更多信息,请参阅 Generics - Associated Types

Thanks to Swift’s type inference, you don’t actually need to declare a concrete Item of Int as part of the definition of IntStack. Because IntStack conforms to all of the requirements of the Container protocol, Swift can infer the appropriate Item to use, simply by looking at the type of the append(_:) method’s item parameter and the return type of the subscript. Indeed, if you delete the typealias Item = Int line from the code above, everything still works, because it’s clear what type should be used for Item.

类型安全和泛型

假设您有以下代码:

struct Helper<T: Numeric> {
    func adder(_ num1: T, _ num2: T) -> T {
        return num1 + num2
    }
    var num: T
}

T 可以是任何数字,例如IntDoubleInt64

然而,一旦您键入 let h = Helper(num: 10),编译器就会假设 T 是一个 Int。它不再接受 DoubleInt64,因为它的 adder func。它只会接受 Int.

这又是因为类型推断和类型安全。

  • 类型推断:因为它必须推断 genericInt.
  • 类型
  • 类型安全:因为一旦T设置为Int类型,它就不再接受Int64Double...

如您在屏幕截图中所见,签名现在更改为仅接受 Int 类型的参数

优化编译器性能的专业提示:

代码的类型推断越少,编译速度就越快。因此,建议避免集合文字。集合越长,其类型推断就越慢...

不错

let names = ["John", "Ali", "Jane", " Taika"]

let names : [String] = ["John", "Ali", "Jane", " Taika"]

有关更多信息,请参阅

另见 Why is Swift compile time so slow?

该解决方案帮助他的编译时间从 10/15 秒减少到一秒。