繁体   English   中英

协议数组元素是按值传递还是按引用传递?

[英]Does protocol array elements passed by value or reference?

我知道结构是按值传递的,而类是在 Swift 中通过引用传递的。

我想知道我是否创建了一个提供协议的数组存储元素。 这些元素是通过值还是引用传递?

它是基于 model a class 还是结构的定义?

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM