Мне нужно реализовать оболочку для стирания стилей для моей собственной структуры, очень похожую на SequenceOf
, GeneratorOf
и т. Д. Поэтому я начал с того, что попытался просто повторно реализовать стандарт SequenceOf
.Как реализуется стандартная оболочка типа стирания?
Я просто скопировал & pasteed в декларации для SequenceOf
, переименовал его в MySequenceOf
и заполняли в некоторых пнях, чтобы получить:
/// A type-erased sequence.
///
/// Forwards operations to an arbitrary underlying sequence with the
/// same `Element` type, hiding the specifics of the underlying
/// sequence type.
///
/// See also: `GeneratorOf<T>`.
struct MySequenceOf<T> : SequenceType {
/// Construct an instance whose `generate()` method forwards to
/// `makeUnderlyingGenerator`
init<G : GeneratorType where T == T>(_ makeUnderlyingGenerator:() -> G) {
fatalError("implement me")
}
/// Construct an instance whose `generate()` method forwards to
/// that of `base`.
init<S : SequenceType where T == T>(_ base: S) {
fatalError("implement me")
}
/// Return a *generator* over the elements of this *sequence*.
///
/// Complexity: O(1)
func generate() -> GeneratorOf<T> {
fatalError("implement me")
}
}
Я получаю ошибку компиляции: "Ни типа в том же типа относится к общему параметру или связанному типу ". Таким образом, я предполагаю, что Xcode сгенерированных декларация SequenceOf
«s„where T == T
“ограничение на самом деле означает„where G.Element == T
“, который дает мне следующую компилируемую-структуру:
struct MySequenceOf<T> : SequenceType {
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator:() -> G) {
fatalError("implement me")
}
func generate() -> GeneratorOf<T> {
fatalError("implement me")
}
}
Так что теперь, достаточно легко, мне просто нужно, чтобы повесить на в makeUnderlyingGenerator
из инициализаторе и вызывать его из generate()
:
struct MySequenceOf<T> : SequenceType {
let maker:()->GeneratorOf<T>
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator:() -> G) {
self.maker = { return makeUnderlyingGenerator() }
}
func generate() -> GeneratorOf<T> {
return self.maker()
}
}
, но это дает мне ошибку: «„G“не конвертируется в„GeneratorOf“»
Это делает компилирует, если я заставляю бросок:
struct MySequenceOf<T> : SequenceType {
let maker:()->GeneratorOf<T>
init<G : GeneratorType where G.Element == T>(_ makeUnderlyingGenerator:() -> G) {
self.maker = { return makeUnderlyingGenerator() as GeneratorOf<T> }
}
func generate() -> GeneratorOf<T> {
return self.maker()
}
}
Но тогда он выходит из строя во время выполнения из динамического гипсе.
Итак, как можно реализовать стирание типа? Это должно быть возможно, потому что стандартная библиотека Swift делает это связкой (SequenceOf, GeneratorOf, SinkOf).
Попробуйте определить тип генератора для вашего типа. –
«Итак, я предполагаю, что объявление Xcode, созданное в соответствии с инструкцией SequenceOf« где T == T », действительно означает« где G.Element == T »« Да, это известная ошибка в том, как объявление отображается в Xcode , Вы не можете сказать 'где T == T', и заголовок Swift на самом деле не говорит об этом. – matt