结构函数和结构静态函数。 (Struct Static Fun 还是值类型吗?)

Posted

技术标签:

【中文标题】结构函数和结构静态函数。 (Struct Static Fun 还是值类型吗?)【英文标题】:Struct Func and Struct Static Func. (Are Struct Static Fun still value type?) 【发布时间】:2021-10-06 13:09:50 【问题描述】:

一直在搜索 SO 并通过谷歌搜索了一个小时。还没有找到确切的答案。因此,请验证我的理解。

结构与类

    在 swift 中默认首选结构。 结构是value type。班级是reference type

图片来自:https://cocoacasts.com/value-types-and-reference-types-in-swift

好的。这一切都很好,花花公子。现在类中的static funcfunc 有什么区别?

static 只是意味着-> 静态,但是当它在一个类中并用于声明一个函数时?什么意思?

static 关键字与 final 类相同。 final 关键字使 变量或函数最终,即它们不能被任何覆盖 继承类。 (link)

class TestStruct 
  var count = Int()

  
  func popeye(name: String) -> String 
    count = count + 1
    return "TestStruct - func popeye - name:\(name) Count:\(count)"
  
  
  static func brutus(name: String) -> String 
    var count = Int() // when declared within the static func
    count = count + 1 // this never gets incremented 

    return "TestStruct - static func brutus - name:\(name) count:\(count)"
  

我试过这个,发现我不能像 foo1.popeye 那样做 foo1.brutus,当它被分配了 static func 关键字时。

但作为 func,我可以有 2 个变量引用同一个函数,并且两者都有自己的值(下面的示例,count 输出不同)。那么使用static 有什么好处呢?我什么时候使用static func

let foo1 = TestStruct()
let foo2 = TestStruct()
var bar1 = foo1.popeye(name: "popeye sailorman")
var bar2 = foo2.popeye(name: "popeye spinach  ")

print("foo1:\(bar1)")
print("foo2:\(bar2)")

bar1 = foo1.popeye(name: "popeye sailorman")
print("foo1:\(bar1)")
print("foo2:\(bar2)")

bar1 = foo1.popeye(name: "popeye sailorman")
print("foo1:\(bar1)")
print("foo2:\(bar2)")

bar1 = foo1.popeye(name: "popeye sailorman")
bar2 = foo2.popeye(name: "popeye spinach  ")
print("foo1:\(bar1)")
print("foo2:\(bar2)")


var oliveOil1 = TestStruct.brutus(name: "Brutus Big ")
var oliveOil2 = TestStruct.brutus(name: "Brutus Mean")
print("oliveOil1:\(oliveOil1)")
print("oliveOil2:\(oliveOil2)")

oliveOil1 = TestStruct.brutus(name: "Brutus Big ")
oliveOil2 = TestStruct.brutus(name: "Brutus Mean")
print("oliveOil1:\(oliveOil1)")
print("oliveOil2:\(oliveOil2)")

导致这些打印输出:

foo1:TestStruct - func popeye - name:popeye sailorman Count:1
foo2:TestStruct - func popeye - name:popeye spinach   Count:1
foo1:TestStruct - func popeye - name:popeye sailorman Count:2
foo2:TestStruct - func popeye - name:popeye spinach   Count:1
foo1:TestStruct - func popeye - name:popeye sailorman Count:3
foo2:TestStruct - func popeye - name:popeye spinach   Count:1
foo1:TestStruct - func popeye - name:popeye sailorman Count:4
foo2:TestStruct - func popeye - name:popeye spinach   Count:2
oliveOil1:TestStruct - static func brutus - name:Brutus Big  count:1
oliveOil2:TestStruct - static func brutus - name:Brutus Mean count:1
oliveOil1:TestStruct - static func brutus - name:Brutus Big  count:1
oliveOil2:TestStruct - static func brutus - name:Brutus Mean count:1

【问题讨论】:

【参考方案1】:

var count = Int() // 在静态函数中声明时 count = count + 1 // 这永远不会增加

您在brutus(name 函数中声明的上述代码是本地变量,与类变量同名。所以 var 的范围在函数内。当函数结束时,函数内部的count var 也结束/释放。

每次调用函数时,您都会创建一个新的count var,因此它总是打印计数 1。

你不能访问静态函数内部的类 var,因为静态函数也需要静态 var。所以很明显,当你在静态函数中打印时,它总是使用本地变量而不是类变量。

那么使用静态有什么好处呢?什么时候使用静态函数

通过使用static 关键字也意味着,您无需创建访问变量或函数的对象。

您可以在使用时看到一些带有 static 关键字的内置函数。

示例: Int 有一个静态函数

@inlinable public static func random(in range: ClosedRange<Int>) -> Int

此函数返回指定范围内的随机 int 值。

所以你可以在不需要创建对象的地方使用静态函数并使用直接函数。

here 是静态函数的一个例子。您可以看到我如何使用静态函数来显示警报控制器。您可以在不想创建对象的地方创建自己的静态函数,然后使用 function 或 var。

【讨论】:

以上是关于结构函数和结构静态函数。 (Struct Static Fun 还是值类型吗?)的主要内容,如果未能解决你的问题,请参考以下文章

linux下判断文件和目录是否存在

九结构和类(结构的概念,类的概念,声明,构造函数,对象的实例化,类和对象的关系,实例的和静态的)

struct stat *buf 这里的stat和*buf分别是啥?

文件权限

struct--二进制数据结构的打包与解包

C++文档阅读笔记-Difference Between C Structures and C++ Structures