Tại sao Swift không cho phép tôi gán giá trị Foo<U>
cho một biến loại Foo<T>
, trong đó U là một phân lớp của T?Tại sao tôi không thể sử dụng một lớp con của một loại chung trong Swift?
Ví dụ:
class Cheese {
let smell: Int
let hardness: Int
let name: String
init(smell: Int, hardness: Int, name: String) {
self.smell = smell
self.hardness = hardness
self.name = name
}
func cut() {
print("Peeyoo!")
}
}
class Gouda: Cheese {
let aged: Bool
init(smell: Int, hardness: Int, name: String, aged: Bool) {
self.aged = aged
super.init(smell: smell, hardness: hardness, name: name)
}
override func cut() {
print("Smells delicious")
}
}
class Platter<Food> {
var food: Food
init(food: Food) {
self.food = food
}
}
let goudaCheese = Gouda(smell: 6, hardness: 5, name: "Gouda", aged: false)
let goudaPlatter = Platter(food: goudaCheese) //Platter<Gouda>
//error: cannot assign value of type 'Platter<Gouda>' to type 'Platter<Cheese>'
let platter: Platter<Cheese> = goudaPlatter
Nhưng tại sao không cho nó hoạt động? Bạn có thể gán cho một biến một đối tượng là một phân lớp của loại đó, ví dụ:
let gouda = Gouda(smell: 6, hardness: 5, name: "Gouda", aged: false)
let cheese: Cheese = gouda
Và bạn có thể thêm lớp con vào bộ sưu tập:
let plainCheese = Cheese(smell: 2, hardness: 5, name: "American")
let gouda = Gouda(smell: 6, hardness: 5, name: "Gouda", aged: false)
var cheeses: [Cheese] = [plainCheese]
cheeses.append(gouda)
Vậy làm thế nào là let platter: Platter<Cheese> = goudaPlatter
khác nhau? Có bất kỳ hoàn cảnh nào không an toàn nếu nó hoạt động không? Nó chỉ đơn giản là một hạn chế của phiên bản hiện tại của Swift?
Không tích cực, nhưng bạn có thể thay đổi 'Platter' cho 'Platter ' (và sau đó 'var thực phẩm: T', 'init (thực phẩm: T)')? –
Connor
Generics là bất biến trong Swift - trong mắt của hệ thống kiểu, 'Platter' và 'Platter ' hoàn toàn không liên quan. Nếu bạn muốn chuyển đổi giữa chúng, bạn cần viết mã để thực hiện chuyển đổi đó. 'Mảng' chỉ là một trường hợp đặc biệt mà trình biên dịch thực hiện một số phép thuật đằng sau hậu trường để thực hiện chuyển đổi này cho bạn (xem ví dụ [câu hỏi này] (http://stackoverflow.com/questions/37188580/why-isnt- somestruct-convertible-to-any)). –
Hamish
Related (có thể là dupe?): [Làm thế nào để lưu trữ một giá trị kiểu Class trong một từ điển kiểu \ [String: Class \] trong Swift?] (Http://stackoverflow.com/q/ 38590548/2976878) –
Hamish