协议数组元素是按值传递还是按引用传递?
Does protocol array elements passed by value or reference?
我知道结构是按值传递的,class在 Swift 中是按引用传递的。
我想知道我是否创建了一个提供协议的数组存储元素。这些元素按值或引用传递?
是基于model a的定义class还是struct?
class ClassA: ProtocolA {
// something
}
struct StructA: ProtocolA {
// something
}
var arr: [ProtocolA] = [ClassA(), StructA()]
exampleFunction(arr[0]) // is it passed by reference
exampleFunction(arr[1]) // is it passed by value
协议应被视为值类型,因为您需要通过将其定义为符合 AnyObject(所有 类 都符合)
来明确告诉编译器它是引用类型
所以如果你有
protocol ProtocolB: AnyObject
那么任何符合 ProtocolB 的类型都将通过引用发送,否则不会。
这是一个简化的例子
protocol ProtocolA {
var x: Int { get set }
}
protocol ProtocolB: AnyObject {
var y: Int { get set }
}
class ClassA: ProtocolA, ProtocolB {
var x = 0
var y = 0
}
func exampleFunction(_ object: ProtocolA) {
object.x += 2 // <-- This will generate a compilation error
}
func exampleFunction(_ object: ProtocolB) {
object.y += 2 // This is fine
}
当您将变量存储为协议类型时,编译器会将其视为值类型来处理。因此,如果 exampleFunction
接受类型为 ProtocolA
的输入参数,为了能够改变输入参数的 属性,您需要将其声明为 inout
.
这并不意味着值必须按值传递,它只是意味着编译器不知道输入参数是值还是引用类型,因此在编译时将其作为值处理类型。
如果您希望能够将协议变量作为引用类型来处理,您需要绑定协议 class。 protocol ProtocolA: class {}
不管数组如何声明,class都是引用传递,结构是值传递。这可以用下面的例子来证明:
protocol ProtocolA {
var title: String { get set}
}
class ClassA: ProtocolA {
var title = "ClassA"
}
struct StructA: ProtocolA {
var title = "StructA"
}
var arr: [ProtocolA] = [ClassA(), StructA()]
print(arr[0].title) // ClassA
print(arr[1].title) // StructA
func exampleFunction(_ obj: ProtocolA) {
var obj = obj // Create local mutable variable
obj.title = obj.title + "!!!"
}
exampleFunction(arr[0])
exampleFunction(arr[1])
print(arr[0].title) // ClassA!!!
print(arr[1].title) // StructA
我知道结构是按值传递的,class在 Swift 中是按引用传递的。
我想知道我是否创建了一个提供协议的数组存储元素。这些元素按值或引用传递?
是基于model a的定义class还是struct?
class ClassA: ProtocolA {
// something
}
struct StructA: ProtocolA {
// something
}
var arr: [ProtocolA] = [ClassA(), StructA()]
exampleFunction(arr[0]) // is it passed by reference
exampleFunction(arr[1]) // is it passed by value
协议应被视为值类型,因为您需要通过将其定义为符合 AnyObject(所有 类 都符合)
来明确告诉编译器它是引用类型所以如果你有
protocol ProtocolB: AnyObject
那么任何符合 ProtocolB 的类型都将通过引用发送,否则不会。
这是一个简化的例子
protocol ProtocolA {
var x: Int { get set }
}
protocol ProtocolB: AnyObject {
var y: Int { get set }
}
class ClassA: ProtocolA, ProtocolB {
var x = 0
var y = 0
}
func exampleFunction(_ object: ProtocolA) {
object.x += 2 // <-- This will generate a compilation error
}
func exampleFunction(_ object: ProtocolB) {
object.y += 2 // This is fine
}
当您将变量存储为协议类型时,编译器会将其视为值类型来处理。因此,如果 exampleFunction
接受类型为 ProtocolA
的输入参数,为了能够改变输入参数的 属性,您需要将其声明为 inout
.
这并不意味着值必须按值传递,它只是意味着编译器不知道输入参数是值还是引用类型,因此在编译时将其作为值处理类型。
如果您希望能够将协议变量作为引用类型来处理,您需要绑定协议 class。 protocol ProtocolA: class {}
不管数组如何声明,class都是引用传递,结构是值传递。这可以用下面的例子来证明:
protocol ProtocolA {
var title: String { get set}
}
class ClassA: ProtocolA {
var title = "ClassA"
}
struct StructA: ProtocolA {
var title = "StructA"
}
var arr: [ProtocolA] = [ClassA(), StructA()]
print(arr[0].title) // ClassA
print(arr[1].title) // StructA
func exampleFunction(_ obj: ProtocolA) {
var obj = obj // Create local mutable variable
obj.title = obj.title + "!!!"
}
exampleFunction(arr[0])
exampleFunction(arr[1])
print(arr[0].title) // ClassA!!!
print(arr[1].title) // StructA