Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:将枚举值转换器函数作为第一类函数调用_Swift_Enums_Coding Style_First Class Functions - Fatal编程技术网

Swift:将枚举值转换器函数作为第一类函数调用

Swift:将枚举值转换器函数作为第一类函数调用,swift,enums,coding-style,first-class-functions,Swift,Enums,Coding Style,First Class Functions,使用上面的枚举,获取行星名称数组的一种方法是调用 enum SolarSystemPlanet: String, CaseIterable { case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune func toRawValue(_ value: SolarSystemPlanet) -> PlanetName { value.rawValue } } 但Swift支

使用上面的枚举,获取行星名称数组的一种方法是调用

enum SolarSystemPlanet: String, CaseIterable {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune

    func toRawValue(_ value: SolarSystemPlanet) -> PlanetName {
        value.rawValue
    }
}
但Swift支持一级函数,将函数视为“一级公民”,这使我们可以像调用任何其他对象或值一样调用函数

因此,通过这个函数获得一个名称数组会很好

SolarSystemPlanet.allCases.map { $0.rawValue }
然而,编译器似乎需要更多的上下文。它无法在编译时推断
map
中的类型,所以我推断了

SolarSystemPlanet.allCases.map(.toRawValue)
编译器停止抱怨,但我没有得到字符串数组。上面的行返回类型为
[(SolarSystemTemplanet)->String]

如果我把上面的打印出来,而不是

SolarSystemPlanet.allCases.map(SolarSystemPlanet.toRawValue)
我得到

如果我强制返回类型为
[String]
如下

[(Function), (Function), (Function), (Function), (Function), (Function), (Function), (Function)]
Xcode会抱怨
[(SolarSystemTemplanet)->String]
无法转换为
[String]

到底有没有可能实现我想做的事情?我是错过了什么还是做错了什么

如果不可能的话,我也非常感谢你解释一下原因

谢谢你花时间阅读我的问题


编辑感谢您的回答

对于那些感兴趣的人,我进一步确保每个字符串枚举都有
toRawValue

var planets: [String] = SolarSystemPlanet.allCases.map(SolarSystemPlanet.toRawValue)

注意:这是Swift 5.1.3

请注意,
toRawValue
不需要是实例方法。它可以是静态的:

extension RawRepresentable where RawValue == String {
    static func toRawValue(_ value: Self) -> PlanetName {
        value.rawValue
    }
}
现在您可以使用
solarSystemTemplanet.toRawValue
作为
map
的参数

或者,在这种情况下,您也可以使用
\.rawValue
的键路径作为
映射
的参数:

static func toRawValue(_ value: SolarSystemPlanet) -> PlanetName {
    value.rawValue
}
这是Swift 5.2的新功能

编辑:解释实例方法不起作用的原因

在Swift中,当从静态上下文访问时,类型
T
上具有签名
(U)->R
的实例方法成为具有签名
(T)->((U)->R)
的静态方法。实例方法需要一个封闭类型的实例来调用,对吗?因此,当您将a
T
传递给它时,它将返回原始实例函数
(U)->R

因此,非静态
SolarSystemTemplanet.toRawValue的类型为

SolarSystemPlanet.allCases.map(\.rawValue)

这就解释了为什么在应用
map
之后,数组会变成
[(SolarSystemTemplanet)->字符串]

非常感谢!这是我的第一个问题,我没想到会有人这么快回答我!根据我在堆栈溢出方面的经验,如果您的问题不太难,它将在一两个小时内得到回答@为什么实例方法不起作用@斯威伯格解释得很清楚。再次感谢您的时间@Sweeper。
SolarSystemPlanet.allCases.map(\.rawValue)
(SolarSystemPlanet) -> ((SolarSystemPlanet) -> String)