Arrays 为什么将数组expressible映射到自身会产生错误?

Arrays 为什么将数组expressible映射到自身会产生错误?,arrays,swift,array-map,Arrays,Swift,Array Map,我正在试验这个: var orientations1: UIInterfaceOrientationMask = [.portrait, .landscapeRight] var orientations2: UIInterfaceOrientationMask = [.portrait, .landscapeRight].map { $0 } orientations1工作正常,但orientations2产生以下错误: 表达式类型不明确,没有更多上下文 UIInterfaceOrienta

我正在试验这个:

var orientations1: UIInterfaceOrientationMask = [.portrait, .landscapeRight]
var orientations2: UIInterfaceOrientationMask = [.portrait, .landscapeRight].map { $0 }
orientations1
工作正常,但
orientations2
产生以下错误:

表达式类型不明确,没有更多上下文


UIInterfaceOrientationTask
间接符合
ExpressibleByArrayLiteral
协议。
.map{$0}
如何可能更改数组的内容,我应该如何使其工作

更新

好吧,这就是我要做的。我正在学习Swift,希望在运行时玩设备方向改变的游戏

我有4个开关:

@IBOutlet weak var switchPortrait: UISwitch!
@IBOutlet weak var switchLandscapeRight: UISwitch!
@IBOutlet weak var switchPortraitUpsideDown: UISwitch!
@IBOutlet weak var switchLandscapeLeft: UISwitch!

var orientationSwitches = [UISwitch]()
var orientations: UIInterfaceOrientationMask = [.portrait, .landscapeRight, .landscapeLeft, .portrait]
viewDidLoad()
方法中,我执行以下操作:

switchPortrait.tag  = Int(UIInterfaceOrientationMask.portrait.rawValue)
switchLandscapeRight.tag = Int(UIInterfaceOrientationMask.landscapeRight.rawValue)
switchPortraitUpsideDown.tag   = Int(UIInterfaceOrientationMask.portraitUpsideDown.rawValue)
switchLandscapeLeft.tag  = Int(UIInterfaceOrientationMask.landscapeLeft.rawValue)

orientationSwitches = [switchPortrait, switchLandscapeRight, switchPortraitUpsideDown, switchLandscapeLeft]

for switchElement in orientationSwitches {
    switchElement.isOn = orientations.contains(UIInterfaceOrientationMask(rawValue: UInt(switchElement.tag)))
}
所以现在每个SwitchUI元素都将其标记设置为适当的方向掩码的原始值。此外,每个开关根据
方向的初始状态打开或关闭

在切换动作时,我尝试更新
方向,如下所示:

@IBAction func orientationSwitched(_ sender: UISwitch) {
    orientations = orientationSwitches.filter({ $0.isOn }).map({ UIInterfaceOrientationMask(rawValue: UInt($0.tag)) }) // doesn't work
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return orientations
}
@IBAction func orientationSwitched(_ sender: UISwitch) {
    orientations = orientationSwitches
        .filter{$0.isOn}
        .map{UIInterfaceOrientationMask(rawValue: UInt($0.tag))}
        .reduce([]) {$0.union($1)}
}
但它不起作用。而我的
支持的界面方向
看起来就像这样:

@IBAction func orientationSwitched(_ sender: UISwitch) {
    orientations = orientationSwitches.filter({ $0.isOn }).map({ UIInterfaceOrientationMask(rawValue: UInt($0.tag)) }) // doesn't work
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return orientations
}
@IBAction func orientationSwitched(_ sender: UISwitch) {
    orientations = orientationSwitches
        .filter{$0.isOn}
        .map{UIInterfaceOrientationMask(rawValue: UInt($0.tag))}
        .reduce([]) {$0.union($1)}
}
我可以通过
insert()
方法为每个UI开关元素执行此操作,但我想了解是否可以通过映射以更优雅的方式执行此操作

表达式类型不明确,没有更多上下文

因为
Map
函数返回一个
array
值作为输出。因此,您需要像这样将推断类型更改为
数组
,以获得所需的
映射
函数输出

let  orientations2: [UIInterfaceOrientationMask] = [.portrait, .landscapeRight].map { $0 }

在Swift中,文字是无类型的,其类型根据上下文推断


在您的情况下,如果Swift将数组文本的类型推断为
数组
,则可以应用
.map{$0}
,但结果也会变成
数组
,并且无法转换为
UIInterfaceOrientationTask
。(见下文。)


如果Swift将数组文字的类型推断为
UIInterfaceOrientationTask
,则
map
不可用

因此,Swift无法找到与您的声明匹配的任何类型,这导致表达式的类型在没有更多上下文的情况下是不明确的


正如您在另一个线程的注释中所建议的那样,
expressiblebyarayliteral
被编译器用来根据上下文解释数组文本。这并不意味着数组可以自动转换为符合
ExpressibleByArrayLiteral
的类型


对于更新


如您所见,
UIInterfaceOrientationTask
没有使用
数组的常用初始值设定项。因此,使用
insert
是一种稳定的方法。稳定的代码比看似聪明但脆弱或难以阅读的代码更优雅

如果你坚持使用看似聪明的代码,你可以这样写:

@IBAction func orientationSwitched(_ sender: UISwitch) {
    orientations = orientationSwitches.filter({ $0.isOn }).map({ UIInterfaceOrientationMask(rawValue: UInt($0.tag)) }) // doesn't work
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return orientations
}
@IBAction func orientationSwitched(_ sender: UISwitch) {
    orientations = orientationSwitches
        .filter{$0.isOn}
        .map{UIInterfaceOrientationMask(rawValue: UInt($0.tag))}
        .reduce([]) {$0.union($1)}
}

UIInterfaceOrientationTask
是一个OptionSet,而不是数组。因此,即使可以使用数组文本初始化它,也不能为它分配数组,这是
map
返回的结果。糟糕但有效:
var-orientations2:uiinterfaceeoorientationmask=[uiinterfaceeoorientationmask.grait.landscapeRight].map{$0}.reduce(uiinterfaceeoorientationmask()){var-result=$0;result.insert($1);return result}
@vacawama,可以使用
union
UIInterfaceOrientationTask()
可以替换为
[]
UIInterfaceOrientationTask
符合
ExpressibleByArrayLiteral
并可以用数组表示。我需要
UIInterfaceOrientationTask
类型,而不是
[UIInterfaceOrientationTask]
@RoboRobok,你的观点有道理。但我想如果你只需要解决这个错误。因此,您可以将推断类型定义为数组。我包含了一些关于我正在尝试执行的操作的更具体的描述。我可以做些什么吗?我想通过一些UI元素的
标记
属性将它们的数组映射到
UIInterfaceOrientationTask
类型。换句话说,我的4个UI元素中的每一个都代表不同的设备方向。@RoboRobok,你真正想做什么还不够清楚。添加一些更具体的示例代码。