Tôi có một giao thức mã cơ sở nhanh chóng của tôi Tôi có giao thức với một loại liên kết và hai phương pháp. Cả hai phương thức xác định các ràng buộc chung khác nhau cho kiểu liên kết của giao thức. Và tôi muốn làm cho cấu trúc phù hợp với hai giao thức nhưng với hai loại liên quan khác nhau.thực hiện giao thức với loại liên quan khác nhau
protocol Convertable {
associatedtype TargetType
func convert() -> TargetType
}
func show<T : Convertable where T.TargetType == String>(toShow : T) {
print(toShow.convert())
}
func add<T : Convertable where T.TargetType == Int>(a : T, b : T) -> Int {
return a.convert() + b.convert()
}
struct MyData {
var data : Int
}
Như một phần mở rộng tôi làm cho struct phù hợp với giao thức nơi TargetType
sẽ String
để vượt qua nó với phương pháp hiển thị:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
}
Cho đến nay mọi thứ hoạt động như mong đợi. Nhưng bây giờ tôi cũng muốn có cấu trúc để phù hợp với giao thức Convertable
khi TargetType
bị ràng buộc với một Int. Điều đó dường như là không thể?
Điều đầu tiên tôi đã cố gắng là để thêm một định nghĩa thứ hai của phương pháp chuyển đổi sang phần mở rộng:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
func convert() -> Int { return data }
}
Trình biên dịch tại phàn nàn rằng MyData
nào không còn phù hợp với các giao thức. Thứ hai là chia thành hai phần mở rộng và ràng buộc TargetType một cách rõ ràng.
extension MyData : Convertable {
typealias TargetType = Int
func convert() -> Int { return data }
}
extension MyData : Convertable {
typealias TargetType = String
func convert() -> String { return String(data) }
}
Điều này có hiệu lực mà trình biên dịch hiện đã khiếu nại TargetType
được xác định lại.
thử cuối cùng của tôi là để xác định hai giao thức mở rộng giao thức Convertable
và hạn chế TargetType
và sau đó thực hiện cả trong số họ thông qua phần mở rộng:
protocol ConvertableString : Convertable {
associatedtype TargetType = String
}
protocol ConvertableInt : Convertable {
associatedtype TargetType = Int
}
extension MyData : ConvertableInt {
func convert() -> Int { return self.data }
}
extension MyData : ConvertableString {
func convert() -> String { return String(self.data) }
}
Mà bây giờ làm cho trình biên dịch hạnh phúc cho các phần mở rộng nhưng không còn cho cuộc gọi đến show
bởi vì nó không biết rằng nó có thể gọi chức năng với MyData
.
Có một số điều mà tôi đã giám sát hoặc hiện tại điều này không thể nhanh chóng?
Hiện tại, không chỉ hiện tại là không thể, nhưng hầu như không bao giờ có thể, theo ý kiến của tôi. Bạn đã khai báo một giao thức với loại _one single_ được kết hợp. Làm thế nào nó có thể được thiết lập để hai loại khác nhau cùng loại ?! – werediver
Vâng, nó không phải là cùng một giao thức, vì giao thức là chung trên TargetType có nhiều biến thể của giao thức như có cho TargetType. Toàn bộ ý tưởng về việc có các kiểu liên kết với các giao thức là bạn có thể phân biệt theo kiểu liên kết của chúng. Nếu bạn nhìn vào C#, có thể thực hiện cùng một giao diện với các kiểu khác nhau được ràng buộc với tham số chung. – Kolja
Vâng, nó không phải là C# và bạn không nên nghĩ về nó vì nó sẽ được, bởi vì điều đó chỉ không hoạt động. – werediver