类型方法和类型实例方法等之间的区别?

Difference between type method and type instance method, etc?

注意:我已经阅读了 apple 文档并学习了 swift 一本书。

  1. 我对 "type instance method"(如果存在,如果我错了请纠正我)和类型方法之间的区别感到困惑?

  2. class方法和实例方法的区别?

  3. 类型 属性 和实例 属性 之间的区别(如果存在,对不起,我对类型属性主题很困惑)?

  4. 最后,class属性是否存在于swift中?

抱歉造成混淆:'(

区别在于实例方法和属性是为每个实例创建的。为整个类型创建类型方法和属性

假设你有 struct Employee

struct Employee {
  static var ID:Int = 0
  static var NAME:Int = 1

  static func getNameOfField(index:Int) -> String {
      var fieldName:String = ""

      if index == ID {
          fieldName = "Id"
      } else if index == NAME {
          fieldName = "Name"
      }

      return fieldName
  }

  var fields = [Int:String]()

  mutating func config(id:String, name:String) {
      fields[Employee.ID] = id
      fields[Employee.NAME] = name
  }

  func getField(index:Int) -> String {
      return fields[index]!
  }
}

var e0 = Employee()
e0.config("1", name: "Mark")

var e1 = Employee()
e1.config("2", name: "John")

print(e0.getField(Employee.NAME))               // prints "Mark"
print(Employee.getNameOfField(Employee.ID))     // prints "Id"

结构 e0 和 e1 的每个实例都有 属性 个字段。它为每个实例创建并存在于其中。存储在字段 属性 中的值对于每个实例都是不同的。这就是为什么它被称为 "instance property"

每个实例也有方法getField。它是为每个实例创建的,并且它可以访问其属性和方法,在这种情况下可以访问实例的 var 字段。这就是为什么它被称为 "instance method"

您通过引用实例(在我们的例子中是 e0 和 e1)来访问实例属性和方法

ID 和 NAME 是类型属性或静态属性。它们只创建一次,并且对每个实例和每个其他对象都具有相同的值。 您可以通过引用 "type"(在我们的例子中是结构)Employee.NAME

来访问类型属性

类型方法有点像类型的全局函数(结构,class,枚举)。它们通常用于封装绑定到类型但可能不需要实例的功能。就像示例中的类型方法 getNameOfField(index:Int) -> String returns 基于索引的字段名称。要 return 此信息,您不必创建一个 Employee

实例

类型是结构,classes 和枚举

您使用关键字 static 定义类型方法和属性(这就是它们也称为静态方法和属性的原因)

结构和枚举可以有类型属性和类型方法。 类 只能有类型方法。您可以创建类型 属性 但它必须是计算类型

在 classes 中,您可以使用 static 或 class 关键字定义类型方法。不同之处在于 class 方法可以被覆盖。

在Swift中,类型命名类型复合类型 . 命名类型包括classes结构枚举,以及 协议 。除了用户定义的命名类型之外,Swift 还定义了许多命名类型,例如数组、字典和可选值。 (让我们暂时忽略复合类型,因为它与您的问题没有直接关系。)

为了回答您的问题,假设我创建了一个名为 Circle 的用户定义 class(这只是一个示例):

class Circle {

    static let PI = 3.14

    var radius: Double

    init(radius: Double) {
        self.radius = radius
    }

    // Returns the area of this circle
    func area() {
        return PI * radius
    }

    // Ridiculous class method for demonstration purposes
    static func printTypeName() {
        println("Circle")
    }
} 
  1. I'm confused on the difference between a "type instance method" (if such exists, correct me if I'm wrong) and a type method?

如前所述,一个类型指的是一个class、结构、枚举、协议和复合类型。在上面的示例中,我使用名为 Circleclass 来定义 type.

如果我想构造圆 class 的单个对象,那么我将创建一个 实例 。例如:

let myCircleInstance = Circle(radius: 4.5)
let anotherCircleInstance = Circle(radius: 23.1)

以上是 Circle 的对象或 实例 。现在我可以直接调用它们的实例方法。我的class中定义的实例方法area.

let areaOfMyCircleInstance = myCircleInstance.area()

现在,类型方法是一种可以在类型上直接调用而无需创建实例的方法那种.

例如:

Circle.printTypeName()

请注意 func 之前有一个 static 限定符。这表明它直接属于类型而不属于类型的实例。

  1. Difference between class method and instance method?

参见上面的解释。

  1. Difference between type property and instance property(if such exists, sorry I'm very confused on Type Properties subject)?

这与您问题一中的解释类似 除了 它不是应用于方法,而是应用于类型的属性(即属性、变量) .

在我的 Circle 示例中,属性定义为:

static let PI = 3.14
var radius: Double

属性PI是一个类型属性;它可以通过

类型直接访问
Circle.PI

属性radius是类型的一个实例属性;它可以被该类型的一个实例访问。使用我们之前创建的变量:

// I can do this; it will be 4.5
myCircleInstance.radius

// And this; it will be 23.1
anotherCircleInstance.radius

// But I CANNOT do this because radius is an instance property!
Circle.radius
  1. Lastly, Do class properties exist in swift?

当然!阅读我对上面问题 3 的解释。我例子中的 PI 属性 是 class 属性.

的例子

参考文献:

whyceewhite - 非常感谢!你澄清了一些我无法理解的事情! 对于那些来到这个页面并且在 Swift 3+ 上运行的人,如果你想把代码付诸实践并看到运行中的静态,请看下面的代码。

class Circle {

static let PI = 3.14

var radius: Double

init(radius: Double) {
    self.radius = radius
}

// Returns the area of this circle
func area() -> Double {
    return Double.pi * radius
}

// Ridiculous class method for demonstration purposes
static func printTypeName() {
    print("Circle")
}
}

然后开始尝试Circle.printTypeName或上面显示的示例!很棒的东西!

一切都与范围有关,它定义了您可以在何处以及如何使用函数的边界。只有在从 class 初始化对象后才能使用方法。简单的说,要使用方法,必须先创建对象,方法属于对象。

但是,如果您需要使用一个方法但不需要启动一个对象,比如全局设置(例如 authorizationStatus() 中的函数 CLLocationManager用于GPS坐标授权),然后可以创建类型方法,只需参考type名称(NOT 对象名称),然后是 classic doc 函数调用。

@PaulBart1 对 @whyceewhite 示例的修复有点棘手,因为他用 swift 替换了已知默认常量 pi 的已声明 PI。 我为 Swift 4 重写了这个示例,如下所示:

class Circle {

//static let PI = 3.14  -> error: static member 'PI' cannot be used on instance of type 'Circle'
    let PI: Double = 3.1415
    var radius: Double

    init (radius: Double) {
        self.radius = radius
    }

    // Return the area of this Circle
    func area() -> Double {
        return PI * radius
    }

    // Radius class method for demonstration purposes
    static func printTypeName() {
        print("Circle")
    }

}

let myCircleInstance = Circle(radius: 4.5)
let anotherCircleInstance = Circle(radius: 23.1)

Circle.printTypeName()   // Circle
print(myCircleInstance.area()) // 14.13675
print(anotherCircleInstance.area()) // 72.56865

 //