Swift类和结构体

1、定义语法

结构体和类有着相似的定义方式,通过 struct 关键字引入结构体,通过 class 关键字引入类:

struct Friend {
    var name:String?
    var age = 12
}

class MyFriends: NSObject {
    var address:String?
    var friendInfo = Friend()
    var height = 180.0
}

2、创建结构体和类的实例

let friend = Friend()

let myFriends = MyFriends()

结构体和类都使用构造器语法来创建新的实例。构造器语法的最简单形式是在结构体或者类的类型名称后跟随一对空括号。通过这种方式所创建的类或者结构体实例,其属性均会被初始化为默认值。

3、通过点语法 访问 类和结构体实例的属性

let friend = Friend()
print(friend.age)
        
let myFriends = MyFriends()
print(myFriends.height)

4、通过点语法 修改 类和结构体实例的属性

let friend = Friend()
friend.name = "kitty"
        
let myFriends = MyFriends()
myFriends.address = "火星小道场"
image.png

瞅瞅,结构体修改属性的时候报错了,为什么呢,修改如下就不会报错了,修改friend为变量。

var friend = Friend()
friend.name = "kitty"

具体原因就是类和结构体的下面的区别了:

5、结构体是值类型
值类型是这样一种类型,当它被赋值给一个变量、常量或者被传递给一个函数的时候,其值会被拷贝

var friend = Friend()
friend.name = "kitty"
var friendB = friend
friendB.name = "hello"

print("friend's name is \(String(describing: friend.name))")
//打印friend's name is Optional("kitty")
print("friendB's name is \(String(describing: friendB.name))")
//打印friendB's name is Optional("hello")

因为 Friend 是一个结构体,所以会先创建一个现有实例的副本,然后将副本赋值给 friend 。尽管 friendB 和 friend 有着相同的name和age,但是在幕后它们是两个完全不同的实例.所以修改friendB的值不会影响到friend的值。

6.类是引用类型
与值类型不同,引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,使用的是已存在实例的引用,而不是其拷贝。

let myFriends = MyFriends()
myFriends.address = "火星小道场"
let myFiendsOth = myFriends
myFiendsOth.address = "月亮小半球"

print("myFriends's address is \(String(describing: myFriends.address))")
//打印myFriends's address is Optional("月亮小半球")
print("myFiendsOth's address is \(String(describing: myFiendsOth.address))")
//打印myFiendsOth's address is Optional("月亮小半球")

因为类是引用类型,所以 myFriends 和 myFiendsOth 实际上引用的是同一个 MyFriends 实例。换句话说,它们是同一个实例的两种叫法.

注意:
这里myFriends声明为常量,但是可以修改他的属性的值,因为myFriends这个常量的值并没有改变,myFriends只是对MyFriends这个实例的引用。
所以:
改变的是底层 MyFriends 实例的 address 属性,而不是指向 MyFriends 的常量引用的值。而结构体是值类型,上面说过值类型在传递过程中值会被拷贝,给结构体的实例friend赋值的时候就是在修改friend属性的值,所以要修改结构体的属性的值,只能声明为变量,而不能是常量,所有值类型的类都是如此。

你可能感兴趣的:(Swift类和结构体)