通用视图生成器无法推断类型swift

时间:2018-04-28 21:17:13

标签: swift generics

有一些困难让我的通用视图生成器工作。

背后的想法是拥有一系列不同的具体视图设置。 生成结果视图我已在下面的pastebin中创建了该函数。

但它无法推断出细胞的正确类型。 任何人都能给我一个暗示吗?

//: Playground - noun: a place where people can play
import UIKit
import PlaygroundSupport

// Protocols
protocol SettingType {
    var color: UIColor { get }
}
protocol CellType {
    func configure(with setting: SettingType)
}

//  Concrete Settings
final class Concrete1Setting: SettingType {
    var color: UIColor = .blue
}

final class Concrete2Setting: SettingType {
    var color: UIColor = .green
}

//  Concrete Cells
final class Concrete1Cell: UIView, CellType {
    func configure(with setting: SettingType) {
        print("Configured Cell 1")
        self.backgroundColor = setting.color
    }
}

final class Concrete2Cell: UIView, CellType {
    func configure(with setting: SettingType) {
        print("Configured Cell 2")
        self.backgroundColor = setting.color
    }
}

//  Generic generator
func makeConcreteCell<S: SettingType, T: CellType>(_ setting: S) -> T {
    switch setting {
    case is Concrete1Setting:
        return Concrete1Cell() as! T
    case is Concrete2Setting:
        return Concrete2Cell() as! T
    default: fatalError()
    }
}

// Test
var cells: [CellType] = [Concrete1Cell(), Concrete2Cell()]
let settings: [SettingType] = [Concrete1Setting(), Concrete2Setting()]
for setting in settings {
    cells.append(makeConcreteCell(setting))         // CompileError: Generic parameter 'S' could not be inferred
}
// expect array equal to [Concrete1Cell, Concrete2Cell]

1 个答案:

答案 0 :(得分:0)

您不需要makeConcreteCell的通用功能。只需要它并返回原型:

func makeConcreteCell(_ setting: SettingType) -> CellType {
    switch setting {
    case is Concrete1Setting:
        return Concrete1Cell()
    case is Concrete2Setting:
        return Concrete2Cell()
    default: fatalError()
    }
}

当您希望编译器为每种特定类型编写特定函数时,将使用泛型。这不是你需要的。一个功能有效。

您想将CellType用作UIView s。

创建一个名为CellTypeClass的基类UIView并采用CellType协议:

// Protocols
protocol SettingType {
    var color: UIColor { get }
}
protocol CellType {
    func configure(with setting: SettingType)
}

//  Concrete Settings
final class Concrete1Setting: SettingType {
    var color: UIColor = .blue
}

final class Concrete2Setting: SettingType {
    var color: UIColor = .green
}

class CellTypeClass: UIView, CellType {
    func configure(with setting: SettingType) {
        fatalError("You must override this function")
    }
}

//  Concrete Cells
final class Concrete1Cell: CellTypeClass {
    override func configure(with setting: SettingType) {
        print("Configured Cell 1")
        self.backgroundColor = setting.color
    }
}

final class Concrete2Cell: CellTypeClass {
    override func configure(with setting: SettingType) {
        print("Configured Cell 2")
        self.backgroundColor = setting.color
    }
}

//  Generic generator
func makeConcreteCell(_ setting: SettingType) -> CellTypeClass {
    switch setting {
    case is Concrete1Setting:
        return Concrete1Cell()
    case is Concrete2Setting:
        return Concrete2Cell()
    default: fatalError()
    }
}

// Test
var cells: [CellTypeClass] = [Concrete1Cell(), Concrete2Cell()]
let settings: [SettingType] = [Concrete1Setting(), Concrete2Setting()]
for setting in settings {
    cells.append(makeConcreteCell(setting))
}