TL; DR
Tại sao tính năng này không hoạt động?Sử dụng init() trong bản đồ()
"abcdefg".characters.map(String.init) // error: type of expression is ambiguous without more context
Chi tiết
Một điều thực sự mát mẻ Tôi thích ở Swift là khả năng chuyển đổi một bộ sưu tập của một điều khác bằng cách đi qua trong một phương thức init (giả định một init()
cho loại đó tồn tại).
Dưới đây là ví dụ chuyển đổi danh sách các bộ dữ liệu thành các phiên bản ClosedInterval
.
[(1,3), (3,4), (4,5)].map(ClosedInterval.init)
Ví dụ đó cũng lợi dụng thực tế là chúng tôi có thể chuyển một đối số làm đối số duy nhất miễn là tuple khớp với danh sách đối số của hàm.
Đây là một ví dụ khác, lần này chuyển đổi danh sách các số thành các thể hiện chuỗi.
(1...100).map(String.init)
Thật không may, ví dụ tiếp theo không hoạt động. Ở đây tôi đang cố gắng chia nhỏ một chuỗi thành một danh sách các chuỗi ký tự đơn.
"abcdefg".characters.map(String.init) // error: type of expression is ambiguous without more context
map()
nên được hoạt động trên một danh sách các Character
(và thực sự tôi đã có thể xác minh trong một sân chơi mà Swift suy luận đúng loại [Character] ở đây được thông qua vào map
).
String
chắc chắn có thể được khởi tạo từ Character
.
let a: Character = "a"
String(a) // this works
Và thú vị, điều này hoạt động nếu các ký tự nằm trong dãy của riêng chúng.
"abcdefg".characters.map { [$0] }.map(String.init)
Hoặc tương đương:
let cx2: [[Character]] = [["a"], ["b"], ["c"], ["d"]]
cx2.map(String.init)
Tôi biết rằng tôi có thể làm điều này:
"abcdefg".characters.map { String($0) }
Nhưng tôi đặc biệt cố gắng tìm hiểu tại sao "abcdefg".characters.map(String.init)
không hoạt động (IMO cú pháp này là cũng dễ đọc và thanh lịch hơn)
Đây là câu trả lời tuyệt vời. Có tài liệu tham chiếu (hoặc thậm chí một bài báo) mô tả bằng cách sử dụng '.init' theo cách này (ví dụ: trong bản đồ/flatMap, v.v ...) không? –
Bạn có thể phân biệt hai initialisers; sử dụng 'String.init (_ :)' để tham chiếu đến cái đầu tiên. – Sweeper