2016-04-30 15 views
9

Theo tài liệu của Apple, Swift không cần thiết phải ghi đè lên bộ khởi tạo. Trong một ví dụ mã sau Bar thừa hưởng initializer của Foo:Tại sao Swift yêu cầu ghi đè lên trình khởi tạo được chỉ định của siêu lớp chung?

class Foo { 
    let value: Int 
    init(value: Int = 5) { 
    self.value = value 
    } 
} 

class Bar: Foo { 
} 

Ngay khi chúng tôi thêm một số generic vào Foo như class Foo<T> { Xcode cung cấp cho chúng ta một lỗi Initializer does not override a designated initializer from its superclass. Có một tài liệu hoặc thảo luận tiến hóa nhanh chóng giải thích tại sao nó đang xảy ra?


Cập nhật. Dường như chung chung không phải là nguyên nhân chính gây ra yêu cầu ghi đè. Dưới đây là một tùy chọn cách xác định lớp có chung không yêu cầu ghi đè của trình khởi tạo được chỉ định:

protocol FooProtocol { 
    associatedtype T 
} 

class Foo<U>: FooProtocol { 
    typealias T = U 

    let value: Int 
    init(value: Int, otherValue: T) { 
     self.value = value 
     self.otherValue = otherValue 
    } 
} 

class Bar: Foo<Int> { 
} 

Tuy nhiên có một quan sát thú vị khác về hành vi. Xác định initializer như sau yêu cầu nguyên nhân override:

init(value: Int = 5) { 
    self.value = value 
} 

Điều điều buồn cười rằng việc thêm một tham số hơn như sau vào như định initializer nguyên nhân yêu cầu ghi đè này để biến mất:

init(value: Int = 5, otherValue: T) { 
    self.value = value 
} 

Cập nhật 2. Tôi không thể tìm thấy một lời giải thích hợp lý để hành vi này, vào thời điểm này tôi đã báo cáo nó như là biên dịch lỗi - https://bugs.swift.org/browse/SR-1375

+0

Tôi đã thực hiện một số thử nghiệm khác và vấn đề dường như là _giá trị mặc định_. Lấy '= 5' ra khỏi các ví dụ của bạn và _none_ trong số chúng dẫn đến lỗi trình biên dịch. – matt

Trả lời

1

Tôi thực sự điền một báo cáo lỗi cho kế thừa từ lớp generic:

enter image description here

Nó đã trở lại trong Tháng 11 năm ngoái và chưa nhận được câu trả lời, vì vậy ¯_ (ツ) _/¯

+0

Cảm ơn. Nó chắc chắn là hữu ích để biết rằng tôi không phải một mình gặp vấn đề này. Trong khi đó tôi không thể đếm tin nhắn này như là một câu trả lời, vì nó không phải là tài liệu cũng không thảo luận tiến hóa nhanh về chủ đề này. –

+0

Tôi đồng ý: rất thú vị, nhưng đây là nhận xét chứ không phải là câu trả lời. – matt

1

Rõ ràng là một lỗi. Hơn nữa, mặc dù lỗi là elicited bằng cách phân lớp chung, nhưng giá trị mặc định gây ra là giá trị mặc định. Đây biên dịch tốt:

class Foo<T> { 
    let value: Int 
    init(value: Int) { 
     self.value = value 
    } 
} 

class Bar: Foo<String> { 
} 

Nhưng điều này không:

class Foo<T> { 
    let value: Int 
    init(value: Int = 5) { 
     self.value = value 
    } 
} 

class Bar: Foo<String> { 
} 

Đó là loại phân biệt tùy ý mà không có một sự khác biệt là một dấu hiệu chắc chắn rằng đây là một lỗi biên dịch.

+0

Tôi nghi ngờ, mặc dù tất nhiên tôi không thể chứng minh, rằng đằng sau hậu trường những gì chứng minh khó hiểu cho trình biên dịch là để gọi 'init (giá trị: Int = 5)' mà không có 'giá trị' sẽ giống như gọi' init '. Tôi không biết tại sao điều đó gây nhầm lẫn trong trường hợp chung chung, nhưng đó là hướng mà các ví dụ của bạn dường như chỉ ra. – matt

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