Reputation: 32271
I want to use a typealias for a function which is used in a generic class. One of the parameters of the function uses a generic type of the class. This is a simplified example:
class Bar {}
// no typealias - works
class TestGeneric<T: Bar> {
let myFunc: (T) -> String
init(myFunc: (T) -> String) {
self.myFunc = myFunc
}
}
let myFunc: (Bar) -> String = {(bar: Bar) in
return "hello"
}
let test = TestGeneric<Bar>(myFunc: myFunc)
println(test.myFunc(Bar()))
// typealias - doesn't compile
class TestTypealias<T: Bar> {
typealias MyFuncGeneric = (T) -> String
let myFunc: MyFuncGeneric
init(myFunc: MyFuncGeneric) {
self.myFunc = myFunc
}
}
let myFunc2: TestTypealias.MyFuncGeneric = {(bar: Bar) in
return "hello"
}
let test2 = TestTypealias<Bar>(myFunc: myFunc2) // Error: Cannot invoke initializer for type 'TestTypealias<Bar>' with an argument list of type '(myFunc: T -> String)'
println(test2.myFunc(Bar()))
Is there a way to solve this? Or do I have to forgo typealias when using generics? In the actual code I have a lot of parameters and really need a typealias...
(Swift 1.2)
Upvotes: 0
Views: 1194
Reputation: 5906
By writing
class TestGeneric<T: Bar>
all you've really done is to define T universally as being of type Bar when used inside of a method, so you can write this:
func myFunc(aValue:T) {
}
instead of this:
func myFunc<T: Bar>(aValue:T) {
}
each time you want to define T as being of type Bar.
If you want the class itself to be generic you use only <T>
, for example: class TestGeneric<T>
and type is defined upon initializing.
class Bar {}
// no typealias - works
class TestGeneric<T> {
let myFunc: (T) -> String
init(myFunc: (T) -> String) {
self.myFunc = myFunc
}
}
let myFunc: Bar -> String = {(bar: Bar) in
return "hello"
}
let test = TestGeneric<Bar>(myFunc: myFunc)
println(test.myFunc(Bar()))
// typealias - doesn't compile
class TestTypealias<T> {
typealias MyFuncGeneric = T -> String
func myFunc(aValue:T) {
}
let myFunc: MyFuncGeneric
init(myFunc: MyFuncGeneric) {
self.myFunc = myFunc
}
}
let myFunc2: TestTypealias<Bar>.MyFuncGeneric = {(bar: Bar) in
return "hello"
}
let test2 = TestTypealias<Bar>(myFunc: myFunc2)
println(test2.myFunc(Bar()))
Upvotes: 1
Reputation: 1194
This compiles and behaves as expected:
class Test< T >
{
typealias GenFunc = ( thing: T ) -> Void
let thing : T
init( thing: T )
{
self.thing = thing
}
func ExecuteFunc( genFunc: GenFunc )
{
genFunc( thing: self.thing )
}
}
Use:
let t = Test( thing: "blah" )
t.ExecuteFunc()
{ ( thing: String ) -> Void in
println( thing )
}
Upvotes: 1