简体   繁体   English

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

[英]What is the difference between Type Safety and Type Inference?

How are they different?它们有何不同? I get a bit confused because they seem to be similar concepts.我有点困惑,因为它们似乎是相似的概念。

How does understanding them help with optimizing compilation time?理解它们如何帮助优化编译时间?

From Swift's own documentation :来自 Swift 自己的文档

Type Safety类型安全

Swift is a type-safe language. Swift 是一种类型安全的语言。 A type safe language encourages you to be clear about the types of values your code can work with.类型安全语言鼓励您明确代码可以使用的值类型。 If part of your code expects a String, you can't pass it an Int by mistake.如果您的代码的一部分需要一个字符串,则不能错误地将它传递给一个 Int。

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

Type Inference类型推断

If you don't specify the type of value you need, Swift uses type inference to work out the appropriate type.如果你没有指定你需要的值的类型,Swift 会使用类型推断来计算出合适的类型。 Type inference enables a compiler to deduce the type of a particular expression automatically when it compiles your code , simply by examining the values you provide.类型推断使编译器能够在编译您的代码时自动推断特定表达式的类型,只需检查您提供的值即可。

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

Type Safety & Type Inference together类型安全和类型推断一起

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'' 

Tricky example for protocols with associated types:具有关联类型的协议的棘手示例:

Imagine the following protocol想象以下协议

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

}

You would adopt it like this:你会像这样采用它:

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

However you can also adopt it like this:但是,您也可以像这样采用它:

struct Website: Identifiable {
    var id: URL
}

You can remove the typealias .您可以删除typealias The compiler will still infer the type.编译器仍然会推断类型。

For more see 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.由于 Swift 的类型推断,您实际上不需要将 Int 的具体项声明为 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.因为 IntStack 符合 Container 协议的所有要求,Swift 可以推断出合适的 Item 使用,只需查看 append(_:) 方法的 item 参数的类型和下标的返回类型。 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.事实上,如果你从上面的代码中删除 typealias Item = Int 行,一切仍然有效,因为很清楚应该为 Item 使用什么类型。


Pro tip to optimize compiler performance:优化编译器性能的专业提示:

The less type inference your code has to do the faster it compiles.您的代码必须执行的类型推断越少,编译速度就越快。 Hence it's recommended to avoid collection literals.因此,建议避免使用集合文字。 And the longer a collection gets, the slower its type inference becomes...并且集合越长,其类型推断变得越慢......

not bad不错

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

good好的

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

For more see this answer .有关更多信息,请参阅此答案

Also see Why is Swift compile time so slow?另请参阅为什么 Swift 编译时间如此之慢?

The solution helped his compilation time go down from 10/15 seconds to a single second.该解决方案帮助他的编译时间从 10/15 秒缩短到一秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM