swift中的struct

346 阅读3分钟

image.png 结构体,自定义类型封装数据。系统提供了基本的数据类型,而struct允许我们以自定义的方式把他们组合起来。

一句话,结构体就是构建自定义的复合类型的数据结构,如果基本类型是乐高拼图中最基本的块,那么结构体就是基本块的排列组合,假设这个结构是车轮,但是放在更大的系统中,车轮也可以看作一个基本块,但是它是一个最基本类型的组合。

第一段描述写到,可以使用与定义,常量,变量,函数相同的语法来定义属性和方法。 所以,结构体中的常量变量叫做属性。结构体中的函数称为称作方法

定义一个struct

image.png

so easy

添加变量

image.png

依旧很easy

初始化结构体

image.png

还是很easy

访问属性

image.png

修改属性

image.png

依旧很easy。接下来该说方法了吧。

image.png

每个结构体都有一个默认的初始化方法。虽然我们没有提供,我只能理解为编译器自动会生成了。

结构体是值类型,赋值的时候会被拷贝一份。

这个也很简单

image.png

image.png

修改cinema的数据,不影响hd的数据。

内存空间变化如下:

image.png

几点需要注意的

1.结构体中的属性可以不用初始化

image.png

如果没有初始化,那么生成的默认的初始化方法就需要传递这个属性值

2.结构体中如果属性给了默认值,那么默认有两个初始化器

image.png

一个问题,结构体中可以定义可选项吗? 可以。

image.png

也会有两个初始化器。

再往下看居然没有讲struct的。

那让我们测试一下吧,在结构体的方法中,能否修改一个变量属性的值。

image.png

发现也改不了,错误提示如下: Left side of mutating operator isn't mutable: 'self' is immutable。 这个就和我们之前遇到的很相似了。self是不可变的。

image.png

我们按照提示修复一下

image.png

的确不报错了。 问题来了。 1.为什么在struct中的方法中不能修改struct中定义的变量,变量不就是可以改变的吗? 2.为什么在方法前面加上关键字mutating就可以了?

image.png

gpt的这个说法点醒了我。 从外部来看,也只有一个结构体被var修饰,才能修改。如果一个结构体是let结构的,那么也是不可以变的。那么let修饰的结构体里面定义var变量岂不是没有意义?

不不不 ,gpt说得很好

  • 定义的时候,你并不知道结构体实例是被let修饰还是var修饰。
  • 实际上用let情况比较少,用var的情况更多
  • 假设,你在内部定义属性为let修饰了,那么即使结构体实例用var修饰了,也无法修改了。

那么如果结构体内部有一个mutating方法,但是结构体实例被let修饰,这个mutating方法还能起作用吗?

image.png

实验证明,的确不会生效了。

问题:那么为啥要这样设计呢? 按照gpt的说法,结构体是值类型,值类型强调的就是不可变性,不让修改就是如此。