Swift中的靜態函數和類函數有什麼區別?

本文翻譯自:What is the difference between static func and class func in Swift?

I can see these definitions in the Swift library: 我可以在Swift庫中看到這些定義:

extension Bool : BooleanLiteralConvertible {
    static func convertFromBooleanLiteral(value: Bool) -> Bool
}

protocol BooleanLiteralConvertible {
    typealias BooleanLiteralType
    class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}

What's the difference between a member function defined as static func and another one defined as class func ? 一個成員函數定義爲static func和另一個成員函數定義爲class func什麼區別? Is it simply that static is for static functions of structs and enums, and class for classes and protocols? 是否僅將static用於結構和枚舉的靜態函數,將class用於類和協議? Are there any other differences that one should know about? 還有其他應該知道的區別嗎? What is the rationale for having this distinction in the syntax itself? 在語法本身中具有這種區別的原理是什麼?


#1樓

參考:https://stackoom.com/question/1hYK1/Swift中的靜態函數和類函數有什麼區別


#2樓

Is it simply that static is for static functions of structs and enums, and class for classes and protocols? 是否僅將static用於結構和枚舉的靜態函數,將class用於類和協議?

That's the main difference. 那是主要的區別。 Some other differences are that class functions are dynamically dispatched and can be overridden by subclasses. 其他一些區別是類函數是動態調度的,並且可以被子類覆蓋。

Protocols use the class keyword, but it doesn't exclude structs from implementing the protocol, they just use static instead. 協議使用class關鍵字,但是它並未從實現協議中排除結構,而是僅使用static。 Class was chosen for protocols so there wouldn't have to be a third keyword to represent static or class. 爲協議選擇了類,因此不必使用第三個關鍵字來表示靜態或類。

From Chris Lattner on this topic: 來自Chris Lattner的以下主題:

We considered unifying the syntax (eg using "type" as the keyword), but that doesn't actually simply things. 我們考慮統一語法(例如,使用“ type”作爲關鍵字),但這實際上並不是簡單的事情。 The keywords "class" and "static" are good for familiarity and are quite descriptive (once you understand how + methods work), and open the door for potentially adding truly static methods to classes. 關鍵字“類”和“靜態”有助於提高熟悉度,並且具有很好的描述性(一旦您瞭解+方法的工作原理),併爲潛在地向類中添加真正的靜態方法打開了大門。 The primary weirdness of this model is that protocols have to pick a keyword (and we chose "class"), but on balance it is the right tradeoff. 該模型的主要怪異之處在於協議必須選擇一個關鍵字(而我們選擇了“類”),但總的來說,這是正確的權衡。

And here's a snippet that shows some of the override behavior of class functions: 這是顯示一些類函數的替代行爲的代碼段:

class MyClass {
    class func myFunc() {
        println("myClass")
    }
}

class MyOtherClass: MyClass {
    override class func myFunc() {
        println("myOtherClass")
    }
}

var x: MyClass = MyOtherClass()
x.dynamicType.myFunc() //myOtherClass
x = MyClass()
x.dynamicType.myFunc() //myClass

#3樓

To declare a type variable property, mark the declaration with the static declaration modifier. 要聲明類型變量屬性,請使用static聲明修飾符標記聲明。 Classes may mark type computed properties with the class declaration modifier instead to allow subclasses to override the superclass's implementation. 類可以使用class聲明修飾符標記類型計算的屬性,以允許子類覆蓋超類的實現。 Type properties are discussed in Type Properties. 類型屬性在類型屬性中討論。

NOTE 注意
In a class declaration, the keyword static has the same effect as marking the declaration with both the class and final declaration modifiers. 在類聲明中,關鍵字static與使用classfinal聲明修飾符標記該聲明具有相同的效果。

Source: The Swift Programming Language - Type Variable Properties 來源: Swift編程語言-類型變量屬性


#4樓

From Swift2.0, Apple says: Apple從Swift2.0中說:

"Always prefix type property requirements with the static keyword when you define them in a protocol. This rule pertains even though type property requirements can be prefixed with the class or static keyword when implemented by a class:" “在協議中定義類型屬性要求時,始終用static關鍵字作爲前綴。即使由類實現時,類型屬性要求可以以class或static關鍵字作爲前綴,該規則也適用:”


#5樓

To be clearer, I make an example here, 更清楚地說,我在這裏舉例說明

class ClassA {
  class func func1() -> String {
    return "func1"
  }

  static func func2() -> String {
    return "func2"
  }

  /* same as above
  final class func func2() -> String {
    return "func2"
  }
  */
}

static func is same as final class func static funcfinal class func相同

Because it is final , we can not override it in subclass as below: 因爲它是final ,所以不能在子類中重寫它,如下所示:

class ClassB : ClassA {
  override class func func1() -> String {
    return "func1 in ClassB"
  }

  // ERROR: Class method overrides a 'final` class method
  override static func func2() -> String {
    return "func2 in ClassB"
  }
}

#6樓

the main difference is that structs are value types and classes are reference types. 主要區別在於結構是值類型,類是引用類型。

When you make a copy of a value type, it copies all the data from the thing you are copying into the new variable. 複製值類型時,它會將您要複製的事物中的所有數據複製到新變量中。 They are 2 seperate things and changing one does not affect the other 它們是2個單獨的東西,而改變它們不會影響另一個

When you make a copy of a reference type, the new variable refers to the same memory location as the thing you are copying. 製作引用類型的副本時,新變量引用與要複製的內容相同的內存位置。 This means that changing one will change the other since they both refer to the same memory location 這意味着更改一個將更改另一個,因爲它們都指向相同的內存位置

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章