2016-04-30 2 views
9

Согласно документации Apple, Swift не требует переопределения инициализатора. В следующем примере кода Bar наследует инициализатор Foo:Почему Swift требует переопределения назначенного инициализатора универсального суперкласса?

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

class Bar: Foo { 
} 

Как только мы добавим некоторые общие в Foo такие как class Foo<T> { Xcode дает нам ошибку Initializer does not override a designated initializer from its superclass. Есть ли документальная или быстрая эволюционная дискуссия, которая объясняет, почему это происходит?


Обновление. Кажется, что generic не является основной причиной для требования переопределения. Вот вариант, как определить класс с родовым, который не требует переопределения назначенного инициализаторе:

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> { 
} 

Однако есть еще одно интересное наблюдение поведения. Определение инициализатору как следующее требование причиной переопределения:

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

Самое смешное, что, что добавление еще один параметр, как следующее в такой назначенный инициализатора причине это требование переопределения исчезнуть:

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

Update 2. Я не могу найти логическое объяснение такого поведения, в этот момент я сообщил об этом, как ошибка компилятора - https://bugs.swift.org/browse/SR-1375

+0

Я сделал еще несколько тестов, и проблема, по-видимому, является значением по умолчанию. Возьмите '= 5' из ваших примеров, а _none_ из них приведет к ошибке компилятора. – matt

ответ

1

Я действительно заполнил отчет об ошибке для наследования от общего класса:

enter image description here

Он вернулся в Ноябрь прошлого года и еще не получил ответа, поэтому ¯_ (ツ) _/¯

+0

Спасибо. Конечно, полезно знать, что я не одинок, испытывая эту проблему. Между тем я не могу сосчитать это сообщение как ответ, так как это ни документация, ни быстрое обсуждение эволюции этой темы. –

+0

Согласен: очень интересно, но это комментарий, а не ответ. – matt

1

Это явно ошибка. Более того, хотя ошибка вызвала путем подклассификации общего типа, ее значение вызывает значение. Это компилируется нормально:

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

class Bar: Foo<String> { 
} 

Но это не делает:

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

class Bar: Foo<String> { 
} 

Такого рода произвольного различия без разницы это верный признак того, что это ошибка компилятора.

+0

Я подозреваю, что, конечно, я не могу доказать, что за кулисами то, что вызывает смущение для компилятора, заключается в том, что вызов 'init (value: Int = 5)' без 'value' будет таким же, как вызов' init '. Я не знаю, почему это сбивает с толку в случае с общим, но это направление, на которое указывают ваши примеры. – matt

Смежные вопросы