2015-12-07 3 views
0

Есть целый ряд других вопросов, плавающих вокруг с различными сложными ответами на этот вопрос, но, насколько я могу судить, ни один из них не ответить на основной вопрос ставятся:Как написать заводскую функцию в быстрой?

Как вы пишете функцию фабрики который принимает тип и возвращает экземпляр , когда тип возврата известен?

То есть:

func factory<T>(T) -> Fooish { ... } 

// Usage: 
class Something : Fooish { ... } 
let x:Fooish = factory(Something) 

Например, этот код:

public class Fooish { 
    var x:String = "" 
    public func foo() -> String { 
    return x 
    } 
} 

public class FooA : Fooish { 
    public override init() { 
    super.init() 
    x = "Hello" 
    } 
} 

public class FooB : Fooish { 
    public override init() { 
    super.init() 
    x = "World" 
    } 
} 

// This works 
print(FooA().foo()) 
print(FooB().foo()) 

// This does not work 
func factory<U>(type:U) -> Fooish { 
    return U() 
} 

print(factory(FooA).foo()) 
print(factory(FooB).foo()) 

Результаты в этой ошибки:

Sources/main.swift:32:10: error: 'U' cannot be constructed because it has no accessible initializers 
    return U() 
    ^
<unknown>:0: error: build had 1 command failures 

Так что является Связанную разместить на T , так что мы можем позвонить T() и знать t hat возвращенный экземпляр - это Fooish?

Некоторые ответы предлагают использовать протокол для него, например:

protocol IsFoo { 
    init() 
} 

factory<T: IsFoo>(t:T) -> Fooish { .. } 

Однако, это не похоже на работу:

error: cannot invoke 'factory' with an argument list of type '((FooA).Type)' 
expected an argument list of type '(U)' 

Каждый ответ на этот вопрос, кажется, есть несколько противоречащих друг другу и обновленные ответы; пожалуйста, просто разместите фрагмент выше, с рабочей реализацией функции factory, для быстрой 2.2.

ответ

3

составляет протокол, который определяет общий инициализатор называться по заводскому способу:

protocol FactoryInitializable { 
    init() 
} 

func factory<T: FactoryInitializable>(type: T.Type) -> T { 
    return T() 
} 

public class Fooish { 
    var x = "" 
    public func foo() -> String { 
    return x 
    } 
} 

public class FooA : Fooish, FactoryInitializable { 
    required public override init() { 
    super.init() 
    x = "This is FooA" 
    } 
} 

public class FooB : Fooish, FactoryInitializable { 
    required public override init() { 
    super.init() 
    x = "This is FooB" 
    } 
} 

let a = factory(FooA) 
let b = factory(FooB) 

print(a.x) // print: This is FooA 
print(b.x) // print: This is FooB 
Смежные вопросы