结构体,自定义类型封装数据。系统提供了基本的数据类型,而struct允许我们以自定义的方式把他们组合起来。
一句话,结构体就是构建自定义的复合类型的数据结构,如果基本类型是乐高拼图中最基本的块,那么结构体就是基本块的排列组合,假设这个结构是车轮,但是放在更大的系统中,车轮也可以看作一个基本块,但是它是一个最基本类型的组合。
第一段描述写到,可以使用与定义,常量,变量,函数相同的语法来定义属性和方法。 所以,结构体中的常量变量叫做属性。结构体中的函数称为称作方法。
定义一个struct
so easy
添加变量
依旧很easy
初始化结构体
还是很easy
访问属性
修改属性
依旧很easy。接下来该说方法了吧。
每个结构体都有一个默认的初始化方法。虽然我们没有提供,我只能理解为编译器自动会生成了。
结构体是值类型,赋值的时候会被拷贝一份。
这个也很简单
修改cinema的数据,不影响hd的数据。
内存空间变化如下:
几点需要注意的
1.结构体中的属性可以不用初始化
如果没有初始化,那么生成的默认的初始化方法就需要传递这个属性值
2.结构体中如果属性给了默认值,那么默认有两个初始化器
一个问题,结构体中可以定义可选项吗? 可以。
也会有两个初始化器。
再往下看居然没有讲struct的。
那让我们测试一下吧,在结构体的方法中,能否修改一个变量属性的值。
发现也改不了,错误提示如下: Left side of mutating operator isn't mutable: 'self' is immutable。 这个就和我们之前遇到的很相似了。self是不可变的。
我们按照提示修复一下
的确不报错了。 问题来了。 1.为什么在struct中的方法中不能修改struct中定义的变量,变量不就是可以改变的吗? 2.为什么在方法前面加上关键字mutating就可以了?
gpt的这个说法点醒了我。 从外部来看,也只有一个结构体被var修饰,才能修改。如果一个结构体是let结构的,那么也是不可以变的。那么let修饰的结构体里面定义var变量岂不是没有意义?
不不不 ,gpt说得很好
- 定义的时候,你并不知道结构体实例是被let修饰还是var修饰。
- 实际上用let情况比较少,用var的情况更多
- 假设,你在内部定义属性为let修饰了,那么即使结构体实例用var修饰了,也无法修改了。
那么如果结构体内部有一个mutating方法,但是结构体实例被let修饰,这个mutating方法还能起作用吗?
实验证明,的确不会生效了。
问题:那么为啥要这样设计呢? 按照gpt的说法,结构体是值类型,值类型强调的就是不可变性,不让修改就是如此。