这篇文章介绍了SwiftUI结构的高级功能,包括初始化器、引用当前实例、惰性、静态属性和访问控制。你将学习如何使用这些功能来创建更强大和灵活的结构,并进行性能优化,限制外部代码的访问等。文章还提供了多个例子,帮助你更好地理解这些概念。
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结
投诉 今天,你将学习结构的一些更高级的功能,这些功能使它们更强大,包括访问控制,静态属性和惰性。是的,懒惰 –比尔·盖茨曾经说过:“我选择一个懒惰的人来做艰苦的工作,因为一个懒惰的人会找到一种轻松的方法来完成它。”在Swift中,惰性是一项重要的性能优化。
初始化程序 初始化程序是为这个结构一个初始值。我们可以使用init
方法来初始化程序,在之前不需要加func
,但是必须要包含所有的参数:
1 2 3 4 5 6 7 8 9 10 11 12 struct Zhhoo { var url: String init () { url = "zhhooo.com" print ("default: \(url) " ) } } var adr = Zhhoo ()adr.url = "blog.zhhooo.com"
其他例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 struct Country { var name: String var usesImperialMeasurements: Bool init (countryName : String ) { name = countryName let imperialCountries = ["Liberia" , "Myanmar" , "USA" ] if imperialCountries.contains(name) { usesImperialMeasurements = true } else { usesImperialMeasurements = false } } }
其他例子:
1 2 3 4 5 6 7 8 9 10 11 struct Cabinet { var height: Double var width: Double var area: Double init (itemHeight : Double , itemWidth : Double ) { height = itemHeight width = itemWidth area = height * width } } let drawers = Cabinet (itemHeight: 1.4 , itemWidth: 1.0 )
引用当前实例(self) 在结构中,我们初始化的时候如果初始化的参数与结构中的参数名称相同时,为了区分,可以用self
点记法来表示不同的位置。self
指的是这个结构,而没有self
指的是这个初始化方法。我们可以使用self
:
1 2 3 4 5 6 7 8 struct Person { var name: String init (name : String ) { print ("\(name) was born!" ) self .name = name } }
为了更好的表达出self
具体指出的位置,我对代码进行了部分修改,用aname
和name
区分:
1 2 3 4 5 6 7 8 9 10 struct Person { var aname: String init (name : String ) { print ("\(name) was born!" ) self .aname = name } } var person = Person (name: "hello" )
其他例子:
1 2 3 4 5 6 7 8 9 10 11 struct Language { var nameEnglish: String var nameLocal: String var speakerCount: Int init (english : String , local : String , speakerCount : Int ) { self .nameEnglish = english self .nameLocal = local self .speakerCount = speakerCount } } let french = Language (english: "French" , local: "français" , speakerCount: 220_000_000 )
其他例子:
1 2 3 4 5 6 7 8 struct Cottage { var rooms: Int var rating = 5 init (rooms : Int ) { self .rooms = rooms } } let bailbrookHouse = Cottage (rooms: 4 )
已经给定默认值后初始化可以不包含该参数。
惰性 我们可以将一个结构作为一个变量插入到另一个结构中,例如我们的第一个例子:
1 2 3 4 5 6 7 8 9 10 11 struct Zhhoo { var url: String init () { url = "zhhooo.com" print ("default: \(url) " ) } } struct Pop { var name = Zhhoo () }
这个时候直接用变量调用Pop
结构会自动创建Zhhoo
结构。有的时候我们做性能优化,创建的结构仅在第一次调用的时候创建。这个时候我们就用到了lazy
。
1 2 3 4 5 6 7 8 9 10 11 12 struct Zhhoo { var url: String init () { url = "zhhooo.com" print ("default: \(url) " ) } } struct Pop { lazy var name = Zhhoo () }
现在只有在调用name
时才会创建Zhhoo
结构:
1 2 var adr = Pop ()adr.name
结构的静态属性 在Swift中我们创建多个结构对应的变量时,我们通常(例:创建班级里的学生):
1 2 3 4 5 6 7 8 9 10 struct Student { var name: String init (name : String ) { self .name = name } } let ed = Student (name: "Ed" )let taylor = Student (name: "Taylor" )
有的时候我们需要结构中有一个不被任何变量/常量影响的变量(例:创建一个学生数量的变量,并在每创建一个学生后,学生总数增加1):
1 2 3 4 5 6 7 8 9 struct Student { static var classSize = 0 var name: String init (name : String ) { self .name = name Student .classSize += 1 } }
因为静态属性classSize
不属于任何变量/常量,所以我们在调用的时候直接调用Student
:
1 print (Student .classSize)
在常规方法引入静态属性需要使用点记法:
1 2 3 4 5 6 7 8 9 10 struct Person { static var population = 0 var name: String init (personName : String ) { name = personName Person .population += 1 } }
访问控制 访问控制可以限制使用代码,你可能希望阻止别人阅读某个属性。例如:
1 2 3 4 5 6 7 8 9 struct Zhhoo { var url: String init (url : String ) { self .url = url } } let website = Zhhoo (url: "zhhooo.com" )print (website.url)
这是一段正常的代码,如果我们要阻止结构外部访问website.url
,我们可以将该属性设置为private
(相反的,允许外部调用设置为public
),例如:
1 2 3 4 5 6 7 struct Zhhoo { private var url: String init (url : String ) { self .url = url } }
现在外部属性无法调用url
,只有内部可以:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 struct Zhhoo { private var url: String init (url : String ) { self .url = url } func go () { print ("Let's go to the \(url) " ) } } let website = Zhhoo (url: "zhhooo.com" )website.go()
使用private
时必须自己创建一个初始化器,否则无法将参数带入到结构中。例如下面这段代码是正确的:
1 2 3 4 struct Contributor { private var name = "Anonymous" } let paul = Contributor ()
这段代码是错误的:
1 2 3 4 5 struct Contributor { var age = 13 private var name = "Anonymous" } let paul = Contributor (age: 13 )
应该为:
1 2 3 4 5 6 7 8 struct Contributor { var age : Int private var name = "Anonymous" init (age : Int ) { self .age = age } } let paul = Contributor (age: 13 )
其他例子:
1 2 3 4 5 6 7 8 9 10 11 struct Office { private var passCode: String var address: String var employees: [String ] init (address : String , employees : [String ]) { self .address = address self .employees = employees self .passCode = "SEKRIT" } } let monmouthStreet = Office (address: "30 Monmouth St" , employees: ["Paul Hudson" ])
其他例子:
1 2 3 4 5 6 7 8 9 struct School { var staffNames: [String ] private var studentNames: [String ] init (staff : String ...) { self .staffNames = staff self .studentNames = [String ]() } } let royalHigh = School (staff: "Mrs Hughes" )
其他例子:
1 2 3 4 5 6 7 8 struct Pokemon { static var numberCaught = 0 var name: String static func catchPokemon () { print ("Caught!" ) Pokemon .numberCaught += 1 } }
总结
你可以使用结构创建自己的类型,这些结构可以具有自己的属性和方法。
你可以使用存储的属性或使用计算的属性即时计算值。
如果要更改方法内的属性,则必须将其标记为mutating。
初始化程序是创建结构的特殊方法。默认情况下,你将获得一个成员初始化器,但是如果创建自己的初始化器,则必须为所有属性赋予一个值。
使用self常量来引用方法内部结构的当前实例。
该lazy关键字告诉斯威夫特当第一次使用,他们只能创建属性。
你可以使用static关键字在结构的所有实例之间共享属性和方法。
访问控制使你可以限制可以使用属性和方法的代码。
参考资料 查看下一天的SwiftUI学习笔记
关于100days英文课程