Reputation: 53
Here's the simplified code that I have:
class MyClass {
func returnSomething(argument: Protocol2) {}
}
protocol Protocol2: Protocol1 where E == Int {
}
protocol Protocol1 {
associatedtype E
func doSomething(_ value: E)
}
Compiler gives me the following error: Protocol 'Protocol2' can only be used as a generic constraint because it has Self or associated type requirements
.
I understand that associated type E needs to be resolved before the protocol can be used as an argument in a function, but given that Protocol2 provides that information, why I still cannot compile that code?
Upvotes: 3
Views: 1387
Reputation: 53
Swift compiler converted my typealias
to the where
clause. (Typealias overriding associated type 'E' from protocol 'Protocol1' is better expressed as same-type constraint on the protocol)
Passing argument indeed works with aforementioned syntax, thank you all!
But how would you return an instance that conforms to Protocol2
?
class ClassConformsToProto2: Protocol2 {
func doSomething(_ value: Int) {
}
}
class MyClass {
func returnSomething<T: Protocol2>() -> T {
return ClassConformsToProto2()
}
}
This code doesn't work.
Cannot convert return expression of type 'ClasConformsToProto2' to return type 'T'
Upvotes: 0
Reputation: 73176
"How to use associated type protocol as argument's type to a function?"
I might not be following what you're asking here, but if a protocol of yours have an associated type, e.g.
protocol DummyNumericTypeWrapper {
associatedtype U: Numeric
static func magic(_ bar: U) -> U
}
You can access this type e.g. in a generic context where the generic placeholder has been constrained to your protocol. To follow up the dummy wrapper above with an entirely dummy example, e.g.:
extension StupidNumericTypeWrapper where U == Int {
static func magic(_ bar: Int) -> Int {
return bar + 42
}
}
func foo<T: StupidNumericTypeWrapper>(_ bar: T.U, _ _ : T.Type) -> T.U {
return T.magic(bar) * T.magic(bar)
}
struct DefaultMagic: StupidNumericTypeWrapper { }
let num = foo(1, DefaultMagic.self)
print(num) // 1849 (43*43)
Upvotes: 0
Reputation: 3606
Since I am learning about Swift generics , so I want to give it a go:
If you want to use Protocol2
as the type of argument in the function returnSomething
As suggested by @Nicolas Miari
class MyClass {
func returnSomething<T: Protocol2>(argument: T) {}
}
Now as the name suggests this function should return something
so
class MyClass {
func returnSomething<T: Protocol2>(argument: T) -> T {
return argument
}
}
Another issue that I see in the original problem is the use of where
clause
I think you want to say the associated type of Protocol1
is Int
you should do it like this
protocol Protocol2: Protocol1 {
typealias E = Int
}
Upvotes: 3