1

Скажем, у меня есть эти протоколыКак сделать пристройку к протоколу, используя associatedtype и массив

protocol Actionable { 

} 

protocol M: class { 
    associatedtype Action: Actionable 
    var views: [Action] { get set } 
} 

и две функции

func f(view: Actionable) { 

} 

func g(views: [Actionable]) { 

} 

И расширить протокол M

extension M { 
    func add(view: Action) { 
     views.append(view) 
     f(view) 
     g(views) 
    } 
} 

Когда я звоните f(view он работает. Но когда я называю g(views) он показывает ошибку

Невозможно преобразовать значение типа '[Self.Action] ожидаемого типа аргумента «[Осуществимый]»

Здесь g принимает массив вместо одного объект, такой как f. Почему массив имеет значение в этом случае? Как обойти это?

Как примечание стороны, это, кажется, вид ошибки для родового структуры, слишком

protocol Actionable { 

} 

struct M<T: Actionable> { 
    var views: [T] 
} 

func g(views: [Actionable]) { 

} 

extension M { 
    func add() { 
    g(views) 
    } 
} 

ответ

1

Это является продолжением того факта, что массивы в Swift имеют ограничения с типами они могут неявно преобразованы в - что является следствием инвариантности дженериков в Свифте, которые я обсуждаю далее in this post.

Одним из возможных решений является использование map для того, чтобы преобразовать каждый элемент в отдельности от Action к Actionable (элементы могут быть свободно перемещаться вверх-бросок, но сам массив не может):

extension M { 
    func add(view: Action) { 
     views.append(view) 
     f(view) 
     g(views.map{$0}) 
    } 
} 

Однако в вашем конкретном ситуация, я просто рекомендую сделать ваши f и g функции общие для того, чтобы поддерживать конкретный тип, который вы указываете на них (если вы специально не хотите, чтобы они были типа стерта):

func f<T:Actionable>(view: T) { 
    ... 
} 

func g<T:Actionable>(views: [T]) { 
    ... 
} 

extension M { 
    func add(view: Action) { 
     views.append(view) 
     f(view) 
     g(views) 
    } 
} 

Теперь общий тип Action будет сохраняться, когда вы их называете, предоставляя вам лучшее безопасности типов, если вы хотите передать спор вокруг.

+0

Ох, спасибо за этот очень подробный ответ – onmyway133

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