ChatGPT解决这个技术问题 Extra ChatGPT

Swift 类中的静态与类函数/变量?

以下代码在 Swift 1.2 中编译:

class myClass {
    static func myMethod1() {
    }
    class func myMethod2() {
    }
    static var myVar1 = ""
}

func doSomething() {
    myClass.myMethod1()
    myClass.myMethod2()
    myClass.myVar1 = "abc"
}

静态函数和类函数有什么区别?我应该使用哪一个,何时使用?

如果我尝试定义另一个变量 class var myVar2 = "",它会说:

类中尚不支持的类存储属性;您指的是“静态”吗?

当支持此功能时,静态变量和类变量(即两者都定义在一个类中)有什么区别?我应该使用哪一个,何时使用?

(Xcode 6.3)

类似的问题在这里:static vs class as class variable/method (Swift)
静态可以应用于存储属性以及计算属性。类只能应用于计算属性。 iosarchitect.com/static-and-class-keyword-in-swift

m
mipadi

staticclass 都将方法与类相关联,而不是与类的实例相关联。不同之处在于子类可以覆盖 class 方法;他们不能覆盖 static 方法。

class 属性理论上会以相同的方式发挥作用(子类可以覆盖它们),但它们在 Swift 中尚不可行。


那么类中的 final class 函数和“静态”函数有什么区别?
@hippo_san,在基类中,两者在功能上是相同的。但是,当在子类中使用时,final 可用于切断进一步的覆盖。两者都有自己的位置,我会说在类函数上使用 staticfinal 是微不足道的,取决于您的风格选择。
啊,所以 Swift 中的 static func foo(){} 就像 Java 中的 public static final foo(){}
@Supuhstar:基本上,是的。
@mipadi 我现在明白了。对于类函数,我们可以将“static”替换为“final class”,但是对于类中的属性,我们可以只有静态属性而不是类属性。所以“静态”关键字仍然有它的位置。
A
Alex Zavatone

我在操场上尝试了 mipadi 的回答和评论。并想分享它。干得好。我认为 mipadi 的回答应该被标记为已接受。

class A{
    class func classFunction(){
    }
    static func staticFunction(){
    }
    class func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
}

class B: A {
    override class func classFunction(){
        
    }
    
    //Compile Error. Class method overrides a 'final' class method
    override static func staticFunction(){
        
    }
    
    //Let's avoid the function called 'classFunctionToBeMakeFinalInImmediateSubclass' being overriden by subclasses
    
    /* First way of doing it
    override static func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
    */
    
    // Second way of doing the same
    override final class func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
    
    //To use static or final class is choice of style.
    //As mipadi suggests I would use. static at super class. and final class to cut off further overrides by a subclass
}

class C: B{
    //Compile Error. Class method overrides a 'final' class method
    override static func classFunctionToBeMakeFinalInImmediateSubclass(){
        
    }
}

e
eMdOS

关于OOP,答案太简单了:

子类可以覆盖类方法,但不能覆盖静态方法。

除了您的帖子之外,如果您想声明一个 class 变量(就像您在 class var myVar2 = "" 中所做的那样),您应该按照以下方式进行:

class var myVar2: String {
    return "whatever you want"
}

A
Alex Protyagov

Swift 4 中的测试显示了模拟器中的性能差异。我用“class func”创建了一个类,用“static func”创建了一个结构,并在测试中运行它们。

静态函数是:

在没有编译器优化的情况下快 20%

启用优化 -whole-module-optimization 时速度提高 38%。

但是,在 iOS 10.3 下的 iPhone 7 上运行相同的代码显示出完全相同的性能。

如果您想测试自己,这里是用于 Xcode 9 的 Swift 4 中的示例项目https://github.com/protyagov/StructVsClassPerformance


这是在模拟器还是物理设备上?
n
nburk

我在我的一个项目中也遇到了这种困惑,发现这篇文章非常有帮助。在我的操场上尝试过同样的方法,这里是总结。希望这有助于具有 staticfinalclass 类型的存储属性和函数、覆盖类变量等的人。

class Simple {

    init() {print("init method called in base")}

    class func one() {print("class - one()")}

    class func two() {print("class - two()")}

    static func staticOne() {print("staticOne()")}

    static func staticTwo() {print("staticTwo()")}

    final func yesFinal() {print("yesFinal()")}

    static var myStaticVar = "static var in base"

    //Class stored properties not yet supported in classes; did you mean 'static'?
    class var myClassVar1 = "class var1"

    //This works fine
    class var myClassVar: String {
       return "class var in base"
    }
}

class SubSimple: Simple {
    //Successful override
    override class func one() {
        print("subClass - one()")
    }
    //Successful override
    override class func two () {
        print("subClass - two()")
    }

    //Error: Class method overrides a 'final' class method
    override static func staticOne() {

    }

    //error: Instance method overrides a 'final' instance method
    override final func yesFinal() {

    }

    //Works fine
    override class var myClassVar: String {
        return "class var in subclass"
    }
}

这是测试样本:

print(Simple.one())
print(Simple.two())
print(Simple.staticOne())
print(Simple.staticTwo())
print(Simple.yesFinal(Simple()))
print(SubSimple.one())
print(Simple.myStaticVar)
print(Simple.myClassVar)
print(SubSimple.myClassVar)

//Output
class - one()
class - two()
staticOne()
staticTwo()
init method called in base
(Function)
subClass - one()
static var in base
class var in base
class var in subclass

y
yoAlex5

Swift 类与静态

[Reference vs Value Type]

classReference Type(类,函数)中使用:

计算属性

方法

可以被子类覆盖

staticReference Type(class, function) 和 Value Type(struct, enum, tuple) 中使用:

计算属性和存储属性

方法

不能被子类改变

protocol MyProtocol {
//    class var protocolClassVariable : Int { get }//ERROR: Class properties are only allowed within classes
    static var protocolStaticVariable : Int { get }
    
//    class func protocolClassFunc()//ERROR: Class methods are only allowed within classes
    static func protocolStaticFunc()
}

struct ValueTypeStruct: MyProtocol {
    //MyProtocol implementation begin
    static var protocolStaticVariable: Int = 1
    
    static func protocolStaticFunc() {
        
    }
    //MyProtocol implementation end
    
//    class var classVariable = "classVariable"//ERROR: Class properties are only allowed within classes
    static var staticVariable = "staticVariable"

//    class func classFunc() {} //ERROR: Class methods are only allowed within classes
    static func staticFunc() {}
}

class ReferenceTypeClass: MyProtocol {
    //MyProtocol implementation begin
    static var protocolStaticVariable: Int = 2
    
    static func protocolStaticFunc() {
        
    }
    //MyProtocol implementation end
    
    var variable = "variable"

//    class var classStoredPropertyVariable = "classVariable"//ERROR: Class stored properties not supported in classes

    class var classComputedPropertyVariable: Int {
        get {
            return 1
        }
    }

    static var staticStoredPropertyVariable = "staticVariable"

    static var staticComputedPropertyVariable: Int {
        get {
            return 1
        }
    }

    class func classFunc() {}
    static func staticFunc() {}
}

final class FinalSubReferenceTypeClass: ReferenceTypeClass {
    override class var classComputedPropertyVariable: Int {
        get {
            return 2
        }
    }
    override class func classFunc() {}
}

//class SubFinalSubReferenceTypeClass: FinalSubReferenceTypeClass {}// ERROR: Inheritance from a final class


g
garg

添加到上述答案静态方法是静态分派意味着编译器知道哪个方法将在运行时执行,因为静态方法不能被覆盖,而类方法可以是动态分派,因为子类可以覆盖这些方法。


p
pkamb

还有一个区别:class 可用于定义仅限计算类型的类型属性。如果您需要存储类型属性,请改用 static

您使用 static 关键字定义类型属性。对于类类型的计算类型属性,您可以使用 class 关键字来允许子类覆盖超类的实现。 https://docs.swift.org/swift-book/LanguageGuide/Properties.html


男人仔细阅读那篇文章并与您的“答案”进行比较。您可以将 static 用于计算属性和存储属性。差异是 use the class keyword instead to allow subclasses to override the superclass’s implementation