Swift基础 结构体

结构体

声明结构体的关键字是struct,使用起来和类相似,但类的成员是引用类型,而结构体的成员是值类型。

值类型在传递和赋值的时候,是进行复制的,那也就是说在修改一处复制体的时候,原来被复制的对象是不受影响的。

引用类型在传递和赋值的时候,是传递引用对象的一个“指向”,所以当对该引用进行修改的时候,是直接直接修改到最原始的对象,即,一旦修改值,则对该原始对象的所有引用都会被同步修改。

在内存中,引用类型的变量是在堆上存储和操作的。值类型的变量是在栈上存储和操作的。两者相比起来,在堆上的变量操作会比较复杂和耗时。所以苹果官方推荐使用结构体,这样可以提高App的运行效率。

结构体的优势:

  • 结构较小,适用于复制,相比一个class的实例被多次引用,struct结构体更加安全。
  • 无须担心内存泄漏或者多线程冲突安全。
    struct student {
    
    
        var name = "name"
        var index = 202100
        var height = 160.00
        var profession = "profession"
        var sex = "男"
    }
    var xiaoMing = student()
    xiaoMing.name = "xiaoMing"
    xiaoMing.index = 202101
    xiaoMing.height = 172.5
    xiaoMing.profession = "计算机科学与技术"
    xiaoMing.sex = "男"
    print("\(xiaoMing)")

运行结果:

student(name: "xiaoMing", index: 202101, height: 172.5, profession: "计算机科学与技术", sex: "男")

当然也可以在定义结构体的时候不给出初始值,而是给出数据的基本类型。

    struct student {
    
    
        var name : String
        var index :Int
        var height :CGFloat
        var profession : String
        var sex : String
    }

因为swift中函数也是一种类型,所以结构体中也可以定义函数。

结构体可以有构造方法

struct Student{
    
    
    //可用结构体名称直接调用属性,不需要创建实例
    static let schoolName = "XXX SCHOOL"
    
    var age:Int
    var name:String
    var score:Float
    var isPass:Bool 
    
    init(name:String,age:Int,score:Float){
    
    
        self.name = name
        self.age = age
        self.score = score
        self.isPass = score < 60 ? false : true
    }
}
var xiaoMing = Student(name: "xiaoMing", age: 18, score: 100)
var xiaoHong = Student(name: "xiaoHong", age: 16, score: 59)
print(xiaoMing)
xiaoHong.age = 18
print(xiaoHong)
print(Student.schoolName)

运行结果:

Student(age: 18, name: "xiaoMing", score: 100.0, isPass: true)
Student(age: 18, name: "xiaoHong", score: 59.0, isPass: false)
XXX SCHOOL

属性观察

struct Student{
    
    
    //可用结构体名称直接调用属性,不需要创建实例
    static let schoolName = "XXX SCHOOL"
    
    var age:Int
    var name:String
    var score:Float = 0{
    
    
        //观察者模式 willSet and didSet
        didSet{
    
    
            isPass = score < 60 ? false : true
        }
    }
    var isPass:Bool = false{
    
    
        //观察者模式 willSet and didSet
        didSet{
    
    
            self.notication = isPass ? "毋需补考":"请周一进行补考"
        }
    }
    
    var notication:String = ""
    
    init(name:String,age:Int){
    
    
        self.name = name
        self.age = age
    }
    
}

var xiaoMing = Student(name: "xiaoMing", age: 18)
var xiaoHong = Student(name: "xiaoHong", age: 16)

print(xiaoMing)
print(xiaoHong)
xiaoMing.score = 98
xiaoHong.score = 52
print(xiaoMing)
print(xiaoHong)

运行结果:

Student(age: 18, name: "xiaoMing", score: 0.0, isPass: false, notication: "")
Student(age: 16, name: "xiaoHong", score: 0.0, isPass: false, notication: "")
Student(age: 18, name: "xiaoMing", score: 98.0, isPass: true, notication: "毋需补考")
Student(age: 16, name: "xiaoHong", score: 52.0, isPass: false, notication: "请周一进行补考") 

下标语法subscript

struct Student{
    
    
    var age:Int
    var name:String
    var classScore:Dictionary<String,Int> = ["chinese":0]

    init(name:String,age:Int){
    
    
        self.name = name
        self.age = age
    }
    
    subscript(index:String)->Int{
    
    
        set{
    
    
            classScore[index] = newValue
        }
        get{
    
    
            return classScore[index] ?? 0
        }
    }
}

var xiaoMing = Student(name: "xiaoMing", age: 18)
var xiaoHong = Student(name: "xiaoHong", age: 16)
print(xiaoMing)
print(xiaoHong)
xiaoMing["chinese"] = 90
xiaoMing["english"] = 75
xiaoHong["chinese"] = 77
xiaoHong["english"] = 88
print(xiaoMing)
print(xiaoHong)

运行结果:
很方便得通过下表语法可以设置一些特别的属性值,在这个案例中,通过下标语法可以设置成员属性课程成绩classScore的字典键值。

Student(age: 18, name: "xiaoMing", classScore: ["chinese": 0])
Student(age: 16, name: "xiaoHong", classScore: ["chinese": 0])
Student(age: 18, name: "xiaoMing", classScore: ["english": 75, "chinese": 90])
Student(age: 16, name: "xiaoHong", classScore: ["english": 88, "chinese": 77])

猜你喜欢

转载自blog.csdn.net/kkkenty/article/details/124607089