当前位置: 首页 > 知识库问答 >
问题:

Swift中的静态函数和类函数有什么区别?

马俊
2023-03-14

我可以在Swift库中看到这些定义:

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

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

定义为静态函数的成员函数和定义为类函数的成员函数之间有什么区别?简单地说,static是用于结构和枚举的静态函数,而class是用于类和协议吗?还有什么其他的不同之处是你应该知道的吗?语法本身有这种区别的理由是什么?

共有3个答案

终子昂
2023-03-14

我在操场上做了一些实验,得到了一些结论。

您可以看到,在的情况下,使用函数静态函数只是一个习惯问题。

游乐场示例及说明:

class Dog {
    final func identity() -> String {
        return "Once a woofer, forever a woofer!"
    }

    class func talk() -> String {
        return "Woof woof!"
    }

    static func eat() -> String {
        return "Miam miam"
    }

    func sleep() -> String {
        return "Zzz"
    }
}

class Bulldog: Dog {
    // Can not override a final function
//    override final func identity() -> String {
//        return "I'm once a dog but now I'm a cat"
//    }

    // Can not override a "class func", but redeclare is ok
    func talk() -> String {
        return "I'm a bulldog, and I don't woof."
    }

    // Same as "class func"
    func eat() -> String {
        return "I'm a bulldog, and I don't eat."
    }

    // Normal function can be overridden
    override func sleep() -> String {
        return "I'm a bulldog, and I don't sleep."
    }
}

let dog = Dog()
let bullDog = Bulldog()

// FINAL FUNC
//print(Dog.identity()) // compile error
print(dog.identity()) // print "Once a woofer, forever a woofer!"
//print(Bulldog.identity()) // compile error
print(bullDog.identity()) // print "Once a woofer, forever a woofer!"

// => "final func" is just a "normal" one but prevented to be overridden nor redeclared by subclasses.


// CLASS FUNC
print(Dog.talk()) // print "Woof woof!", called directly from class
//print(dog.talk()) // compile error cause "class func" is meant to be called directly from class, not an instance.
print(Bulldog.talk()) // print "Woof woof!" cause it's called from Bulldog class, not bullDog instance.
print(bullDog.talk()) // print "I'm a bulldog, and I don't woof." cause talk() is redeclared and it's called from bullDig instance

// => "class func" is like a "static" one, must be called directly from class or subclassed, can be redeclared but NOT meant to be overridden.

// STATIC FUNC
print(Dog.eat()) // print "Miam miam"
//print(dog.eat()) // compile error cause "static func" is type method
print(Bulldog.eat()) // print "Miam miam"
print(bullDog.eat()) // print "I'm a bulldog, and I don't eat."

// NORMAL FUNC
//print(Dog.sleep()) // compile error
print(dog.sleep()) // print "Zzz"
//print(Bulldog.sleep()) // compile error
print(bullDog.sleep()) // print "I'm a bulldog, and I don't sleep."
宣俊豪
2023-03-14

更清楚地说,我在这里举个例子,

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

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

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

静态函数最终类函数相同

因为它是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"
  }
}
樊俊悟
2023-03-14

简单地说,static是用于结构和枚举的静态函数,而class是用于类和协议吗?

这是主要的区别。其他一些不同之处在于类函数是动态调度的,并且可以被子类重写。

协议使用class关键字,但它并不排除structs实现协议,它们只是使用static。为协议选择了Class,这样就不必有第三个关键字来表示static或Class。

来自Chris Lattner关于这个话题:

我们考虑过统一语法(例如,使用“type”作为关键字),但这实际上并不简单。关键字“class”和“static”对于熟悉性很好,并且具有相当的描述性(一旦您理解了+方法的工作原理),并且为潜在地将真正静态的方法添加到类中打开了大门。这个模型的主要怪异之处在于,协议必须选择一个关键字(我们选择了“class”),但总的来说,这是一个正确的折衷。

下面的片段显示了类函数的一些重写行为:

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
 类似资料:
  • 问题内容: 我可以在Swift库中看到这些定义: 定义为的成员函数与定义为的另一个成员函数有什么区别?仅仅是为了结构和枚举的静态功能,以及用于类和协议吗?还有其他应该知道的区别吗?在语法本身中具有这种区别的原理是什么? 问题答案: 是否仅将static用于结构和枚举的静态函数,将class用于类和协议? 那是主要区别。其他一些区别是类函数是动态调度的,并且可以被子类覆盖。 协议使用class关键字

  • 我找不到和之间的任何区别。据我所知,类静态函数不能被继承,struct也没有继承的选项。 请不要被类中的静态函数和类函数所混淆。 VS

  • 问题内容: 我想创建一个将保留所有实用程序方法的类,并将在整个应用程序中使用这些方法。 问题:1 创建一个单例类并在其中保留所有必需的方法是好事,还是应该创建一个所有函数都是静态的类? 问题:2 快速的上述两种方法之间的主要区别是什么? 问题:3 它会如何影响iOS的性能? 问题答案: 当然,这听起来令人困惑并且可以辩论。但是,从最佳实践中,我可以提出一些建议。 Singleton 通常用于创建资

  • 问题内容: 以下代码在Swift 1.2中进行编译: 静态 函数和 类 函数有什么区别?我应该使用哪一个?何时使用? 如果我尝试定义另一个变量,它说: 类中尚不支持的类存储属性;您是说“静态”吗? 如果支持此功能,则 静态 变量和 类 变量之间有什么区别(即,当两者都在类中定义时)?我应该使用哪一个?何时使用? (Xcode 6.3) 问题答案: 和与类两者关联的方法,而不是一个类的实例。区别在于

  • 问题内容: 我一直以为功能和方法是相同的,直到我通过“ Swift编程语言”电子书学习Swift 之前。我发现我 不能greet(“John”, “Tuesday”)用来调用在类中声明的函数, Here is the code:- 当我在Objective-C中编程时,我从未意识到这种差异。 Swift中的函数和方法之间有什么区别? 在Swift中什么时候使用函数以及何时使用方法? 问题答案: 经

  • 问题内容: 我试图弄清楚如何声明一个静态变量,其范围仅限于Swift中的函数。 在C中,这可能看起来像这样: 在Objective-C中,基本上是相同的: 但是我似乎无法在Swift中做这样的事情。我尝试通过以下方式声明变量: 但是这些都会导致错误。 第一个抱怨“静态属性只能在类型上声明”。 第二个抱怨“期望的声明”(在哪里)和“期望的模式”(在哪里) 第三条抱怨“一行上的连续语句必须用’;’分隔