В Swift мы можем инициировать необязательную переменную не сразу, а позже в блоке if else, например:
let result: Bool
if something {
result = computeSomething()
} else {
result = computeSomethingElse()
}
Но что, если моя переменная имеет тип протокола? (в моем примере я хотел бы сделать это с помощью GraphQLMutation, который является протоколом):
let mutation: GraphQLMutation
if something {
mutation = StartMutation()
} else {
mutation = StopMutation()
}
self.graphQLDataSource.set(mutation: mutation)
Ошибка компилятора Swift говорит:
Protocol 'GraphQLMutation' can only be used as a generic constraint because it has Self or associated type requirements
Любая идея, чтобы иметь возможность сделать это и избежать повторения кода?
Вы должны звонить self.graphQLDataSource.set(...) в каждую из веток if, другого пути нет.





Он работает с протоколами:
protocol Foo {}
struct A: Foo {}
class B: Foo {}
let x: Foo
if Bool.random() {
x = A()
} else {
x = B()
}
Это просто не работает с протоколами, у которых есть связанный тип. Вы можете использовать его только в универсальной функции. Вот код, демонстрирующий это:
protocol Foo {
associatedtype T
}
struct A: Foo {
typealias T = Int
}
class B: Foo {
typealias T = String
}
func x<Foo>(_ test: Bool) -> Foo? {
let x: Foo?
if test {
x = A() as? Foo
} else {
x = B() as? Foo
}
return x
}
let a1: A? = x(true) // => A
let a2: A? = x(false) // => nil
let b1: B? = x(true) // => nil
let b2: B? = x(false) // => B
Для a1 мы получаем экземпляр A, поскольку приведение A() as? Foo сработало, потому что оно имеет тип Foo со связанным типом Int, требуемым let a1: A?.
Для a2 мы получаем nil, так как приведение B() as? Foo терпит неудачу, потому что оно не может быть приведено к Foo со связанным типом Int, требуемым let a2: A?.
Для b1 мы получаем nil, так как приведение A() as? Foo терпит неудачу, потому что оно не может быть приведено к Foo со связанным типом String, требуемым let b1: B?.
Для b2 мы получаем экземпляр B, поскольку приведение B() as? Foo сработало, потому что оно имеет тип Foo со связанным типом String, требуемым let b2: B?.
Большое спасибо! Это имеет смысл :)
@MathieuVandeginste тогда смело принимайте ответ! :)
Какое определение у
GraphQLMutation,StartMutationиStopMutation?