2016-09-05 16 views
7
protocols.forEach { $0.prop = nil } 

kết quả trong:

Cannot assign to property: '$0' is immutable 

tôi làm việc xung quanh này với:

protocols.forEach 
{ 
    var protocol = $0 

    protocol.prop = nil 
} 

Nhưng tại sao là trình biên dịch ổn với điều này? Tôi hy vọng nó có thể hình dung ra điều này.

+0

Các vật thể có cấu trúc hoặc thể hiện của một lớp không? – vacawama

+0

@ vacawama Không, cảm ơn vì đã hỏi, họ thực sự là 'giao thức'. –

+0

Thêm '": class "' vào giao thức của bạn nếu mọi thứ triển khai giao thức của bạn là một lớp và nó sẽ hoạt động. – vacawama

Trả lời

17

Bạn có một loạt các mục triển khai giao thức. Nếu bạn không nói với Swift rằng đây là giao thức class, nó sẽ giả định rằng giao thức có thể được thực hiện bởi struct.

Trong vòng lặp forEach, về cơ bản bạn sẽ có biến số let (được gọi là $0 theo mặc định) được gán cho từng giá trị trong mảng lần lượt. Nếu bạn có một mảng các đối tượng (các thể hiện của một lớp), thì bạn có thể sửa đổi các thuộc tính của mục đó. Nếu bạn có một mảng gồm struct mục thì những mục đó sẽ không thay đổi. Nếu bạn có một mảng các mục thực hiện giao thức, thì Swift sẽ coi chúng là hạn chế hơn struct trừ khi bạn thêm : class vào định nghĩa giao thức của mình.

Ví dụ:

protocol Xyzzy: class { 
    var prop: Int? { get set } 
} 

class Fred: Xyzzy, CustomStringConvertible { 
    var description: String { return "\(prop)" } 
    var prop: Int? = 17 
} 

let objects: [Xyzzy] = [Fred(), Fred(), Fred()] 

print(objects) // [Optional(17), Optional(17), Optional(17)] 

objects.forEach { $0.prop = nil } 

print(objects) // [nil, nil, nil] 

workaround của bạn:

protocols.forEach 
{ 
    var protocol = $0 

    protocol.prop = nil 
} 

công trình cho các đối tượng lớp vì nó tạo ra một con trỏ var mới cho đối tượng, và sau đó cho phép bạn chỉnh sửa các đối tượng. Lưu ý, cách giải quyết này chỉ hoạt động đối với các phiên bản của các lớp. Nếu giao thức của bạn được thực hiện bởi struct, thì var mới sẽ là bản sao mới của mục struct và các bản gốc trong mảng sẽ không bị thay đổi.

+0

Câu trả lời hay giúp hiểu sâu hơn về Swift. Cảm ơn bạn! –

Các vấn đề liên quan