我是靠谱客的博主 快乐寒风,最近开发中收集的这篇文章主要介绍Swift 类,结构体,枚举使用总结类,结构体,枚举相同与不同引用类型的特点static 和 classstatic与protocol,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
类,结构体,枚举相同与不同
相同之处在于:
1:都可以通过定义不同的属性来保存自己的数据.2:都可以通过定义方法来实现不同的功能.
3:都可以在定义下标方法后,通过下标方法的语法来获取和修改自己保存的值.
4:都可以定义构造器来设置不同属性的初始值.
5:都可以使用extention关键字来扩充其功能.
6:都可以遵守协议来通过特定种类的功能.
不同之处:
1:类支持继承.2:类支持类型转换,允许你在运行时检测和解释类实例的类型,也就是多态.
3:类支持析构,可以自动回收类实例说掌控的资源.
4:类实例支持自动引用计数(ARC).
5:类属于引用类型,而枚举和结构体属于值类型.枚举,结构体因为是值类型,所以没有ARC.
值类型的特点如下:
1:在赋值给常量或变量的过程中,赋给变量或常量的是该类型的值的一个副本.
2:在作为参数传递给函数时,传递的是该类型的副本.
3:值类型之特权--变质方法.(注意:在 swift 中除了类都是值类型.)在实例方法中有一个特殊的方法,称之为变质方法.是因为它可以直接修改当前实例,而不是在当前实例的基础上修改其中的某些属性,该方法是值类型的专属方法,即只能够用在结构体和枚举类型上.
下面看一个有关于变质方法的例子:
struct Warcraft{
var sense: String
var money: Int
mutating func jumpToSense(sense: String){
//直接生成一个新的Warcraft实例,而不是单纯地修改sense和money.
self = Warcraft(sense: sense, money: 100)
}
}
func testOne(){
//新的游戏,新的场景游戏币为200
var myWarcraft = Warcraft(sense: "无间地狱", money: 200)
//疯狂练级,赚了1000金币
myWarcraft.money = 1000
print("当前场景:(myWarcraft.sense) 当前金币:(myWarcraft.money)")
//当前场景:无间地狱 当前金币:1000
//水平太差,死掉,恢复到魔域之火场景,金币丢失.这里直接重置当前实例!
myWarcraft.jumpToSense("魔域之火")
print("当前场景:(myWarcraft.sense) 当前金币:(myWarcraft.money)")
//当前场景:魔域之火 当前金币:100
}
引用类型的特点
在赋值做作为参数传递给函数时,传递的不是一个值副本,而是对同一现有实例的一个引用!
//引用类型代码:
class SomeClass{
var name: String
init(name: String){
self.name = name
}
}
//值类型代码:
struct SomeSturct{
var name: String
init(name: String){
self.name = name
}
}
func testTwo(){
var aClass = SomeClass(name: "jack")
var bClass = aClass //aClass和bClass是对同一实例的引用.
bClass.name = "jenny"
//因为类是引用类型,所以结果必然一样.
print("aClass.name=(aClass.name) bClass.name=(bClass.name)")
//aClass.name=jenny bClass.name=jenny
var aStruct = SomeSturct(name: "lisa")
var bStruct = aStruct
bStruct.name = "judy"
print("aStruct.name=(aStruct.name) bStruct.name=(bStruct.name)")
//aStruct.name=lisa bStruct.name=judy
if aClass === bClass{
print("aClass和bClass引用了同一类实例")
}
if !(aClass !== bClass){
print("aClass和bClass引用了同一类实例")
}
//以上两个判断语句都输出:aClass和bClass引用了同一类实例
}
有上面的例子我们就能够明白:
1:引用类型在赋值和作为参数传递的过程中,传递的是对该类实例的一个引用.我们一旦通过引用修改了该类实例中属性的值,将会导致其它所有引用该类实例的常量或者变量中的属性发生改变.2:值类型则不会,因为值类型传递的是该实例的一个副本,内存中两个实例拥有不同的内存地址,所以当我们修改了bStruct中属性的 name的值后,并不会同时修改aStruct中属性name的值.
这里注意,如果不确定常量或者变量是否引用了相同的类实例,可以通过===和!==来判断两个不同的常量或者变量是否引用了同一个类实例.
建议:在绝大多数情况下我们应该使用类来封装自定义数据类型,只有在满足如下条件下,应优先考虑结构体.
1:只是用于封装简单的数据时,如位置信息.
2:该封装数据中的值在赋值或者传参时,应该是传复制的值而不是传引用的值,如 swift 中基本的数据类型Int,Double,String等.
3:该类型需要独立存在,不需要任何继承关系,多态特性时选用结构体.
4:记住:类是属性和方法的集合,而结构体和枚举是关联数据的集合.
static 和 class
Swift 中表示 “类型范围作用域” 这一概念有两个不同的关键字,它们分别是static和class。在非clasa的类型上下文中,我们统一使用static来描述类型作用域。这包括在enum和struct中表述类型方法和类型属性时。在这两个值类型中,我们可以在类型范围内声明并使用存储属性,计算属性和方法.static适用的场景有这些:
struct Point {
let x: Double
let y: Double
//存储属性
static let zero = Point(x: 0, y: 0)
//计算属性
static var ones: [Point] {
return [Point(x:1, y:1)]
}
//类方法
static func add(_ p1: Point, _ p2: Point) -> Point {
return Point(x: p1.x + p2.x, y: p1.y + p2.y)
}
}
enum的情况与这里类似。对于class关键字相比起来就明白许多,是专門用在class 类型的上下文中的,可以用来修饰类方法以及类的计算属性。但是有一个例外,class中现在是不能出现class的存储属性的,我们如果写类似这样的代码的话:
class Person {
class var age: Int?
}
但是我们可以使用static
class Person {
static var age: Int?
}
static与protocol
在Swift中class,enum,struct都是可以实现某个protocol的。那么如果我们想在protocol里定义一个类型域上的方法或者计算属性的话,我们可以使用static进行定义。在使用的时候,enum或struct仍然使用static,而在class里我们既可以使用class关键字,也可以用static,它们的结果是相同的:
protocol MyProtocol {
static func foo() -> String
}
struct MyStruct: MyProtocol {
static func foo() -> String {
return "MyStruct"
}
}
enum MyEnum: MyProtocol {
static func foo() -> String {
return "MyEnum"
}
}
class MyClass: MyProtocol {
class func foo() -> String {
return "MyClass.foo()"
}
static func bar() -> String {
return "MyClass.bar()"
}
}
最后
以上就是快乐寒风为你收集整理的Swift 类,结构体,枚举使用总结类,结构体,枚举相同与不同引用类型的特点static 和 classstatic与protocol的全部内容,希望文章能够帮你解决Swift 类,结构体,枚举使用总结类,结构体,枚举相同与不同引用类型的特点static 和 classstatic与protocol所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复