#ios #arrays #swift
#iOS #массивы #swift
Вопрос:
Для удобства в рамках небольшого эксперимента, который я провожу, я хотел бы расширить массив, чтобы предоставить некоторые функции, специфичные для приложения. Это конкретное расширение не является необходимой передовой практикой, но мне просто интересно решить возникающие у меня проблемы со Swift.
Учитывая раздел пользовательского класса, мое расширение (с частично расширенным закрытием) является:
extension Array {
func onlyFullSection() -> Array<Section> {
return self.filter {
(a:Section) -> Bool in
return a.isFullSection()
}
}
}
Я получаю ошибку: «T» не является подтипом «Section».
Я пытался исправить это со всеми соусами (изменение типов, приведение и т.д.), Но все равно получаю похожие ошибки.
Этот другой вариант:
extension Array {
func onlyFullSection() -> Array<Section> {
return (self as Array<Section>).filter {
(a:Section) -> Bool in
return a.isFullSection()
} as Array<Section>
}
выдает: Cannot convert the expression's type 'Array<Section>' to type 'Array<Section>'
Есть какие-нибудь подсказки о том, что я делаю неправильно? Спасибо!
Ответ №1:
Это потому, что вы расширяете T[], а не Section[] . Это означает, что у Int[] также будет ваш дополнительный метод. Это может быть не лучшей идеей (поскольку это приведет к серьезному сбою).
В настоящее время Swift не позволяет расширять специализированный универсальный тип, такой как Section[].
Но если вы действительно, действительно хотите это сделать, вот один из способов принудительного приведения, используйте reinterpretCast
, который Apple описывает следующим образом
/// A brutal bit-cast of something to anything of the same size
func reinterpretCast<T, U>(x: T) -> U
Вы можете использовать его следующим образом:
extension Array {
func onlyFullSection() -> Section[] {
let sections : Section[] = reinterpretCast(self)
return sections.filter{ $0.isFullSection() }
}
}
Но, пожалуйста, не делайте этого.
Ответ №2:
Проблема в том, что, поскольку Array
класс на самом деле является универсальным Array<T>
, вы расширяете Array<T>
. И, по-видимому, вы не можете выполнять преобразование между универсальными типами (т. Е. <T>
в <Section>
), поэтому я полагаю, вам придется создать новый массив и просто вставить в него соответствующие объекты.
17> extension Array {
18. func onlyFullSection() -> Array<Section> {
19. var ary = Array<Section>()
20. for s in self {
21. if (s as Section).isFullSection() {
22. ary.append(s as Section)
23. }
24. }
25. return ary
26. }
27. }
Вы также могли бы создать вспомогательный метод для преобразования между универсальными типами для вас, но в данном случае это просто создало бы ненужный временный объект.
Помните, что язык все еще сильно меняется, поэтому возможно, что это изменится. Я думаю, маловероятно, что мы получим возможность выполнять приведение между универсальными типами, но я надеюсь, что мы, по крайней мере, сможем расширить определенные универсальные типы.