【问题标题】:What is the difference between Type Safety and Type Inference?类型安全和类型推断有什么区别?
【发布时间】:2016-10-09 00:16:03
【问题描述】:

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

理解它们对优化编译时间有何帮助?

【问题讨论】:

    标签: swift optimization type-inference type-safety compilation-time


    【解决方案1】:

    来自 Swift 自己的documentation

    类型安全

    Swift 是一种类型安全的语言。类型安全的语言鼓励你清楚你的代码可以使用的值的类型。 如果你的部分代码需要一个字符串,你不能错误地传递一个 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

    多亏了 Swift 的类型推断,你实际上不需要声明一个 Int 的具体项目作为 IntStack 定义的一部分。因为 IntStack 符合 Container 的所有要求 协议,Swift 可以推断出要使用的适当项目,只需通过 查看 append(_:) 方法的 item 参数的类型和 返回下标的类型。事实上,如果你删除 typealias Item = 上面代码中的 int 行,一切仍然有效,因为很清楚应该为 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),编译器就会假定TInt。它不再接受DoubleInt64,因为它的adder 函数。它只会接受Int

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

    • 类型推断:因为它必须推断出 generic 的类型是 Int
    • 类型安全:因为一旦将T 设置为Int 类型,它将不再接受Int64Double...

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

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

    你的代码需要做的类型推断越少,它的编译速度就越快。因此,建议避免使用集合文字。而且一个集合的时间越长,它的类型推断就越慢......

    还不错

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

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

    更多信息请见this answer

    另见Why is Swift compile time so slow?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-02
      • 2013-12-27
      • 2010-10-02
      • 2010-12-11
      • 2023-02-18
      • 1970-01-01
      • 2023-01-04
      相关资源
      最近更新 更多