Предположим, например, что мы говорим об элементах типа Int (но вопрос по-прежнему применяется к любому типу)
У меня есть функциональность, которая должна зацикливаться на последовательности Ints. Но мне все равно, если за кулисами эта последовательность реализована как массив или набор или любой другой экзотический тип структуры, единственное требование состоит в том, что мы можем перебирать их.
Стандартная библиотека Swift определяет протокол SequenceType как "Тип, который можно повторить с помощью цикла for... in loop". Поэтому мой инстинкт заключается в том, чтобы определить такой протокол:
protocol HasSequenceOfInts {
var seq : SequenceType<Int> { get }
}
Но это не работает. SequenceType не является общим типом, который может быть специализированным, это протокол. Любой конкретный SequenceType имеет определенный тип элемента, но доступен только как связанный тип: SequenceType.Generator.Element
Итак, вопрос:
Как мы можем определить протокол, который требует определенного типа последовательности?
Вот некоторые другие вещи, которые я пробовал и почему они не правы:
Ошибка 1
protocol HasSequenceOfInts {
var seq : SequenceType { get }
}
Протокол "SequenceType" может использоваться только в качестве общего ограничения потому что он имеет собственные или связанные требования типа
Ошибка 2
protocol HasSequenceOfInts {
var seq : AnySequence<Int> { get }
}
class ArrayOfInts : HasSequenceOfInts {
var seq : [Int] = [0,1,2]
}
Я думал, что это сработает, но когда я попытался выполнить конкретную реализацию с помощью массива, мы получим
Тип 'ArrayOfInts' не соответствует протоколу 'HasSequenceOfInts'
Это потому, что Array не является AnySequence (к моему удивлению... я ожидал, что AnySequence будет соответствовать любой последовательности Ints)
Ошибка 3
protocol HasSequenceOfInts {
typealias S : SequenceType
var seq : S { get }
}
Компилирует, но нет никаких обязательств, чтобы элементы последовательности seq имели тип Int
Ошибка 4
protocol HasSequenceOfInts {
var seq : SequenceType where S.Generator.Element == Int
}
Невозможно использовать предложение where
Итак, теперь я полностью из идей. Я просто могу просто заставить мой протокол требовать Массив Int, но тогда я ограничиваю реализацию без уважительной причины, и это очень неуправляемо.
Успех обновления
См. ответ от @rob-napier, который очень хорошо объясняет ситуацию. Моя неудача 2 была довольно близка. Использование AnySequence может работать, но в вашем соответствующем классе вам нужно убедиться, что вы конвертируете из любой последовательности, которую вы используете в AnySequence. Например:
protocol HasSequenceOfInts {
var seq : AnySequence<Int> { get }
}
class ArrayOfInts : HasSequenceOfInts {
var _seq : [Int] = [0,1,2]
var seq : AnySequence<Int> {
get {
return AnySequence(self._seq)
}
}
}