区别:
- class是引用类型,struct是值类型;(本质区别)
- class可以继承类、接口和被继承,struct只能继承接口,不能被继承;
- class有默认的无参构造函数,有析构函数;
struct没有默认的无参构造函数,且只能声明有参的构造函数,没有析构函数; - class声明的方法修改属性不需要mutating关键字;struct需要
- class支持引用计数(Reference counting);struct不支持
- class支持Type casting;struct不支持
- class实例由垃圾回收机制来保证内存的回收处理,而struct变量使用完后立即自动解除内存分配;
1.本质区别:
类是引用类型,实例是通过引用传递
引用类型:
在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝
结构体是值类型,实例是通过值传递
值类型:
它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制
import UIKit
print("class=======")
class TestClass {
var a : Int
init(a:Int){
self.a=a
}
}
let c1 = TestClass(a:1)
let c2 = c1
print(c1.a)//1
print(c2.a)//1
c2.a = 5
print(c1.a)//5
print(c2.a)//5
print("struct=======")
struct TestStruct {
var a : Int
}
let s1 = TestStruct(a:1)
var s2 = s1
print(s1.a)//1
print(s2.a)//1
s2.a = 5
print(s1.a)//1
print(s2.a)//5
2.继承 实现接口的区别.
- class可以继承类、接口和被继承
- struct只能继承接口,不能被继承
print("class=======")
class BaseClass{
var a : Int?
func test(){
print("可以被继承")
}
}
protocol InterfaceTest {
func test()
}
class TestClass:BaseClass {
var b : String?
override func test() {
print("可以继承类")
}
}
class Test1Class:InterfaceTest {
func test() {
print("可以实现接口")
}
var b : String?
}
let t = TestClass()
t.test()//可以继承类
let t1 = Test1Class()
t1.test()//可以实现接口
print("struct=======")
struct TestStruct:InterfaceTest {
var a : Int
var b : String?
func test() {
print("只能实现接口")
}
}
//struct Test1Struct:TestStruct {//Inheritance from non-protocol type 'TestStruct'
// 不能被继承
//}
let s = TestStruct(a: 1)
s.test()//只能实现接口
3.默认构造器,析构函数的区别
- class有默认的无参构造函数; 有析构函数
- struct没有默认的无参构造函数,且只能声明有参的构造函数(系统自动生成各种组合的init方法); 没有析构函数;
import UIKit
print("class=======")
class TestClass {
var a : Int?
var b : String?
deinit {
//有析构函数
}
}
let t = TestClass()
//let t = TestClass(a:1,b:"")//Argument passed to call that takes no arguments
//一个类定义后,系统默认只会生成无参数的init方法
print("struct=======")
struct TestStruct {
var a : Int
var b : String?
// deinit {//Deinitializers may only be declared within a class
// //没有析构函数
// }
}
let s = TestStruct(a: 1)
let s1 = TestStruct(a: 1,b:"")
//定义了一个结构体后,系统自动生成各种组合的init方法.
4.class声明的方法修改属性不需要mutating关键字;struct需要
import UIKit
protocol InterfaceTest{
mutating func test()
}
print("class=======")
class TestClass:InterfaceTest{
var a : Int = 0
var b : String = ""
func test() {
a=a+1
print("在 class 中实现带有mutating方法的接口时,不用mutating进行修饰。因为对于class来说,类的成员变量和方法都是透明的,所以不必使用 mutating 来进行修饰")
}
func test1(){
b = "change"
print("class声明的方法修改属性不需要mutating关键字")
}
}
let t = TestClass()
t.test()
t.test1()
print("struct=======")
struct TestStruct:InterfaceTest{
var a : Int = 0
var b : String = ""
mutating func test() {
a = a+1 //Cannot assign to property: 'self' is immutable
print("在struct中实现带有mutating方法的接口时,需要mutating进行修饰")
}
mutating func test1(){
b = "change"//Cannot assign to property: 'self' is immutable
print("struct声明的方法修改属性需要mutating关键字")
}
}
var s = TestStruct(a: 1)
s.test()
s.test1()
https://www.jianshu.com/p/4e180a3da1ff
https://www.jianshu.com/p/bde0fd4e56b4
https://www.jianshu.com/p/2fbbbfd45d04
https://juejin.cn/post/6844903775816155144