【问题标题】:Swift generic function call underlying method based on generic typeSwift泛型函数调用基于泛型类型的底层方法
【发布时间】:2018-02-25 05:45:16
【问题描述】:

我正在为别人的代码 (SEC) 编写一个接口,并且我有一长串或多或少像这样的函数:

public func readString(_ row: Row, columnName: String) -> String? {
    return SEC.getString(row, columnName)
}

public func readInt(_ row: Row, columnName: String) -> Int? {
    return SEC.getInt(row, columnName)
}

等等。

我想做的是有一个单一的功能:

public func read<T>(_ row: Row, columnName: String) -> T? {
    // call correct SEC.get* method
}

我在TT.Type 上尝试了一个简单的 switch 语句,但没有骰子。我还尝试了上述的修改版本:

public func read<T: ReadableType>(_ row: Row, columnName: String) -> T? {
    let getter = T.getterMethod
    return getter(row, columnName)
}

我可以在其中创建具有SEC.get* 函数的元类型的enum,并对其进行扩展以返回正确的getter 方法。这对我来说似乎很理想。唉:

public enum ReadableTypes {
    case String.Type       // nope
    case Int.self          // also nope
}

我不确定还可以尝试什么;如果我只有一打 read* 方法,这还不是世界末日,但如果我可以将其设为通用,调用此方法的代码可能会非常紧凑。

【问题讨论】:

    标签: swift generics metatype


    【解决方案1】:

    您可以像这样单独测试通用占位符代表什么类型:

    if T.self is Int.Type //...
    

    同样的测试可以在switch..case 语句中完成。

    假设SECSECType 类型,我要做的是扩展SECType 以拥有一个通用的get 方法,该方法以返回类型为键:

    extension SECType {
      public func get<T>(_ row: Row, _ columnName: String) -> T? {
        // switch on the generic type
        switch T.self {
        // As much as I dislike force-unwrapping an Optional
        // this is about as safe as it gets.
        case is Int.Type   : return getInt   (row, columnName) as! T?
        case is String.Type: return getString(row, columnName) as! T?
        //...
        default: return nil
        }
      }
    }
    

    现在您可以编写自己的read 函数,例如:

    public func read<T>(_ row: Row, columnName: String) -> T? {
      return SEC.get(row, columnName)
    }
    

    当然,您可以跳过extension,而只使用switch 执行通用函数。但是,将方法添加到类型中是无害的,并且类型具有这样的泛型方法是有意义的。

    【讨论】:

    • 非常酷,但请注意,OP 实际问题的答案只是短语if T.self is Int.Type。这是他的谜题中缺失的部分——询问通用占位符已解析到的类型的语法。
    • @matt 没错,可以归结为那个短语。我使用switch 来展示如何一次涵盖多个测试,因为有人提到有一个“长长的功能列表”像这样。我会将其添加到答案中以澄清,谢谢。
    • 绝对 - 我只是在回应他的“我在 T 和 T.Type 上尝试了一个简单的 switch 语句”。他没有在 T.self 上尝试过,也没有想过要与 Int.Type 进行比较(仅 Int 不起作用,因为它不是元类型)。
    • 谢谢!我要花很长时间才能达到他们想要的语法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    相关资源
    最近更新 更多