在Swift中,你可以将属性的名称传递给函数吗?

b09cbbtk  于 2023-08-02  发布在  Swift
关注(0)|答案(1)|浏览(111)

我有一个结构体,包含一堆引用不同类型统计数据的属性。示例对象是:

class Stats {
    var stats: [Stat]
}
struct Stat {
    var id: UUID
    var countA: Int
    var countB: Int
    var countC: Int
    var totalAAttempts: Int
    var totalBAttempts: Int
    var totalCAttempts: Int
    ...
}

字符串
我用类中的一堆函数来显示百分比...

class Stats {
    var stats: [Stat]
    var countAPerc: Double {
        let totalA = stats.reduce(0) { total, stat in
            total + stat.countA
        }
        let totalAttemps = stats.reduce(0) { total, stat in
            total + stat.totalAAttempts
        }
        return Double(totalA) / Double(totalAttempts)
    }
    var countAPercDisplay: String {
        String(format: "%.1f", countAPerc * 100) + "%"
    }
    var countBPerc: Double {
        let totalB = stats.reduce(0) { total, stat in
            total + stat.countB
        }
        let totalAttemps = stats.reduce(0) { total, stat in
            total + stat.totalBAttempts
        }
        return Double(totalB) / Double(totalAttempts)
    }
    var countBPercDisplay: String {
        String(format: "%.1f", countBPerc * 100) + "%"
    }
    ...
}


有没有可能在函数中指定属性名作为参数,以防止重复编写相同的代码?类似于:

func summarizeProperty(_ countProperty: PROPERTYNAME1, _ totalProperty: PROPERTYNAME2) -> Double {
    let totalCount = stats.reduce(0) { total, stat in
        total + stat.PROPERTYNAME1
    }
    let totalAttemps = stats.reduce(0) { total, stat in
        total + stat.PROPERTYNAME2
    }
    return Double(totalCount) / Double(totalAttempts)
}

func summarizedProperty(_ countProperty: PROPERTYNAME1, _ totalProperty: PROPERTYNAME2) -> String {
    let summarized = summarizeProperty(PROPERTYNAME1, PROPERTYNAME2)
    return String(format: "%.1f", summarized * 100) + "%"
}


然后叫它...

Text(summarizedProperty(countA, totalAAttempts))


提前致谢

jogvjijk

jogvjijk1#

您需要的工具是KeyPath

func summarizeProperty(_ countProperty: KeyPath<Stat, Int>, _ totalProperty: KeyPath<Stat, Int>) -> Double {
    let totalCount = stats.reduce(0) { total, stat in
        total + stat[keyPath: countProperty]
    }
    let totalAttempts = stats.reduce(0) { total, stat in
        total + stat[keyPath: totalProperty]
    }
    return Double(totalCount) / Double(totalAttempts)
}

字符串
KeyPath<Stat, Int>是Stat上的属性,返回一个Int。它使用keyPath:下标访问,通常使用\语法创建:

Stats().summarizeProperty(\.countA, \.totalAAttempts)


KeyPaths是普通值,可以像这样传递:

func summarizedProperty(_ countProperty: KeyPath<Stat, Int>, _ totalProperty: KeyPath<Stat, Int>) -> String {
    let summarized = summarizeProperty(countProperty, totalProperty)
    return String(format: "%.1f", summarized * 100.0) + "%"
}

相关问题