2015-01-18 23 views
13

Tôi đã trải qua các câu hỏi tương tự nhưng vẫn không hiểu tại sao mã của tôi lại ném lỗi.(String: AnyObject) không có thành viên có tên 'subscript'

var dict = [String:AnyObject]() 
dict["participants"] = ["foo", "bar"] 
dict["participants"][0] = "baz" 

Lỗi này là trên dòng 3: (String: AnyObject) does not have a member named 'subscript'

Tôi đang thiết chìa khóa participants để một mảng và sau đó cố gắng cập nhật các yếu tố đầu tiên của nó mà không có bất kỳ may mắn. Đoạn mã trên được rút ngắn cho các mục đích ví dụ, nhưng tôi đang sử dụng [String:AnyObject] vì nó không chỉ là mảng được lưu trữ trong từ điển.

Đó có thể là điều gì đó thực sự tầm thường nhưng tôi vẫn còn mới với Swift. Nhờ sự giúp đỡ trước!

Trả lời

19

Thông báo lỗi cho bạn biết chính xác vấn đề là gì. Các giá trị từ điển của bạn được nhập là AnyObject. Tôi biết bạn biết rằng giá trị này là một mảng chuỗi, nhưng Swift không biết điều đó; nó chỉ biết những gì bạn nói với nó, rằng đây là một AnyObject. Nhưng AnyObject không thể được subscripted (trên thực tế, bạn không thể làm gì nhiều với nó cả). Nếu bạn muốn sử dụng subscripting, bạn cần phải nói với Swift rằng đây không phải là một AnyObject mà là một mảng của một số loại (ở đây, một mảng của String).

Sau đó, có vấn đề thứ hai, tức là dict["participants"] không thực sự là ngay cả một AnyObject - đó là một Tùy chọn gói một AnyObject. Vì vậy, bạn sẽ phải unwrap nó cast nó để subscript nó.

Sau đó, có vấn đề thứ ba, đó là bạn không thể thay đổi giá trị mảng bên trong từ điển tại chỗ. Bạn sẽ phải trích xuất giá trị, thay đổi nó, và sau đó thay thế nó.

Vì vậy, toàn bộ mã của bạn sẽ trông như thế này:

var dict = [String:AnyObject]() 
dict["participants"] = ["foo", "bar"] 
var arr = dict["participants"] as [String] // unwrap the optional and cast 
arr[0] = "baz" // now we can subscript! 
dict["participants"] = arr // but now we have to write back into the dict 

tắm cho các chuyên gia: Nếu bạn muốn trở thành disgustingly mát và Swifty (và những người không ??), bạn có thể thực hiện đột biến và chuyển nhượng trong một lần di chuyển bằng cách sử dụng hàm ẩn danh xác định và gọi, như sau:

var dict = [String:AnyObject]() 
dict["participants"] = ["foo", "bar"] 
dict["participants"] = { 
    var arr = dict["participants"] as [String] 
    arr[0] = "baz" 
    return arr 
}() 
+0

Bạn có thể giải thích tại sao bạn đã gõ 'dict' là' [String: AnyObject] 'ở vị trí đầu tiên? Tôi không nói rằng không có lý do để làm như vậy, nhưng nếu mọi giá trị sẽ đi đến một mảng của String bạn cũng có thể nói như vậy lên phía trước. Nếu không, bạn sẽ phải bỏ. – matt

+0

Vâng, xin lỗi tôi nên rõ ràng hơn về điều đó. Đoạn mã trên là nhiều hơn cho các mục đích ví dụ nhưng sẽ không luôn luôn là một mảng. Trong một số trường hợp, nó sẽ có các kiểu dữ liệu khác. Tôi sẽ cập nhật câu hỏi. – Fenda

+0

@Fenda Hoàn toàn hợp lý; việc này xảy ra mọi lúc. Nhưng sau đó bạn cần phải đúc. Tôi đã cập nhật câu trả lời của mình để chứng minh. – matt

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