为什么映射数组本身可以产生错误?

时间:2017-08-06 20:25:59

标签: arrays swift array-map

我正在尝试这个:

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

orientations1工作正常,但orientation2会产生以下错误:

  

如果没有更多的上下文,表达的类型是不明确的

UIInterfaceOrientationMask间接符合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)))
}

所以现在每个开关UI元素都将其标记设置为适当的方向掩码的原始值。此外,根据初始状态orientations,每个开关都打开或关闭。

在切换操作时,我正在尝试像这样更新orientations

@IBAction func orientationSwitched(_ sender: UISwitch) {
    orientations = orientationSwitches.filter({ $0.isOn }).map({ UIInterfaceOrientationMask(rawValue: UInt($0.tag)) }) // doesn't work
}

但它不起作用。我的supportedInterfaceOrientations看起来很像:

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return orientations
}

我可以通过insert()方法为每个UI切换元素执行此操作,但我想了解是否可以通过映射以更优雅的方式完成。

2 个答案:

答案 0 :(得分:1)

  

如果没有更多的上下文,表达的类型是不明确的

因为Map函数返回array值作为输出。因此,您需要将推断类型更改为array,以获得所需的map函数输出。

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

答案 1 :(得分:1)

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

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

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

因此,Swift找不到与您的声明匹配的任何类型,这会导致 map

正如您在另一个线程的注释中所建议的那样,编译器使用Type of expression is ambiguous without more context来根据上下文解释数组文字。这并不意味着数组可以自动转换为符合ExpressibleByArrayLiteral的类型。

更新

如您所见,ExpressibleByArrayLiteral没有通常的初始化程序使用UIInterfaceOrientationMask。所以使用Array是一种稳定的方式。稳定的代码比看似聪明但易碎或难以阅读的代码更优雅。

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

insert