快速影响 inout 通用变量的值

标签 swift generics inout

我想用 T 变量简化这段代码,但无法编译成功。希望你能给我指路。

这是我要重写的“重复”代码:

    func getIntegerValue (listValues: [Any], numValueToRead: Int, readValue: inout Int) -> Bool {
        if numValueToRead < 0 || numValueToRead >= listValues.count {
            return false
        }
        let value = listValues [numValueToRead]
        if type (of: value) == type(of: readValue) {
            readValue = value as! Int
            return true
        } else {
            return false
        }
    }

    func getStringValue (listValues: [Any], numValueToRead: Int, readValue: inout String) -> Bool {
        if numValueToRead < 0 || numValueToRead >= listValues.count {
            return false
        }
        let value = listValues [numValueToRead]
        if type (of: value) == type(of: readValue) {
            readValue = value as! String
            return true
        } else {
            return false
        }
    }

这是我写的但没有编译的代码:

func getValue <T> (listValues: [Any], numValueToRead: Int, readValue: inout T) -> Bool {
    if numValueToRead < 0 || numValueToRead >= listValues.count {
        return false
    }
    let value = listValues [numValueToRead]
    if type (of: value) == type(of: readValue) {
        switch value {
        case let integerValue as Int:
            readValue = integerValue
        case let stringValue as String:
            readValue = stringValue
        default:
            return false
        }
        return true
    } else {
        return false
    }
}

因为这些矫揉造作,我得到了那些编译错误: readValue = integerValue -> 'Int' 不可转换为 'T' readValue = stringValue -> 'String' 不可转换为 'T'

有没有一种方法可以使用泛型将我的两个函数与一个独特的函数合成?

最佳答案

理论上,您可以通过添加强制转换使其编译,因为您已经知道 value 的类型为 T:

    case let integerValue as Int:
        readValue = integerValue as! T
    case let stringValue as String:
        readValue = stringValue as! T

但更好的解决方案是使用条件转换 (as?T) 和 条件绑定(bind)(if let):

func getValue<T>(listValues: [Any], numValueToRead: Int, readValue: inout T) -> Bool {
    if numValueToRead < 0 || numValueToRead >= listValues.count {
        return false
    }
    let value = listValues[numValueToRead]
    if let tvalue = value as? T {
        readValue = tvalue
        return true
    } else {
        return false
    }
}

然后适用于任意类型,不仅是 IntString

“更快捷”的方法是返回一个可选值(nil 表示“无值(value)”)。然后代码可以简化为

func getValue<T>(listValues: [Any], numValueToRead: Int) -> T? {
    guard listValues.indices.contains(numValueToRead) else {
        return nil
    }
    return listValues[numValueToRead] as? T
}

关于快速影响 inout 通用变量的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49084525/

相关文章:

WPF - 可以将 List<T> 用作依赖项属性

ios - UIView 在运行时不会改变

amazon-web-services - 使用 Swift 进行 Amazon AWS DynamoDB 查询的最佳方式?

java - 这个特定的集合如何适合特定的场景?

arrays - 当所有类型都正确定义时,为什么 Swift 的 reduce 函数会抛出 'Type of expression ambigious without more context' 错误?

swift - 符号 (&) 在 Swift 语言中是什么意思?

swift - 当 .isEmpty != nil 时正确输出但 else 语句中没有输出

ios - 如何使用swift在firebase上上传多张图片?

mysql - SELECT 语句在 MySQL 存储的 PROCEDURE 中有意义吗?

const 属性的 Swift inout 参数