为什么可表达到自身的映射数组会产生错误?
Why does mapping array expressible to itself produce error?
我正在试验这个:
var orientations1: UIInterfaceOrientationMask = [.portrait, .landscapeRight]
var orientations2: UIInterfaceOrientationMask = [.portrait, .landscapeRight].map { [=10=] }
orientations1
工作正常,但 orientation2
产生以下错误:
Type of expression is ambiguous without more context
UIInterfaceOrientationMask
间接符合 ExpressibleByArrayLiteral
协议。 .map { [=19=] }
怎么可能改变数组的内容,我应该怎么做才能让它工作?
更新
好的,这就是我正在尝试做的事情。我正在学习 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({ [=13=].isOn }).map({ UIInterfaceOrientationMask(rawValue: UInt([=13=].tag)) }) // doesn't work
}
但是没用。我的 supportedInterfaceOrientations
看起来就像这样:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return orientations
}
我可以通过 insert()
方法为每个 UI 开关元素做到这一点,但我想了解是否可以通过映射以更优雅的方式完成。
Type of expression is ambiguous without more context
因为 Map
函数 returns 一个 array
值作为输出。因此,您需要像这样将推断类型更改为 array
以获得所需的 map
函数输出。
let orientations2: [UIInterfaceOrientationMask] = [.portrait, .landscapeRight].map { [=10=] }
在 Swift 中,文字是无类型的,它们的类型是根据上下文推断的。
在你的例子中,如果 Swift 推断数组文字的类型为 Array< UIInterfaceOrientationMask>
,你可以应用 .map{ [=12=] }
,但结果也变成 Array<UIInterfaceOrientationMask>
而不能转换为 UIInterfaceOrientationMask
。 (见下文。)
如果 Swift 将数组文字的类型推断为 UIInterfaceOrientationMask
,则 map
不可用。
因此,Swift 找不到与您的声明匹配的任何类型,这导致 Type of expression is ambiguous without more context
.
正如您在另一个线程的评论中所建议的那样,编译器使用 ExpressibleByArrayLiteral
根据上下文解释数组文字。并不意味着数组可以自动转换为符合ExpressibleByArrayLiteral
.
的类型
对于更新
如您所见,UIInterfaceOrientationMask
没有采用 Array
的常用初始化程序。所以使用 insert
是一种稳定的方式。稳定的代码比看似聪明但脆弱或难以阅读的代码更优雅。
如果你坚持使用看似聪明的代码,你可以这样写:
@IBAction func orientationSwitched(_ sender: UISwitch) {
orientations = orientationSwitches
.filter{[=10=].isOn}
.map{UIInterfaceOrientationMask(rawValue: UInt([=10=].tag))}
.reduce([]) {[=10=].union()}
}
我正在试验这个:
var orientations1: UIInterfaceOrientationMask = [.portrait, .landscapeRight]
var orientations2: UIInterfaceOrientationMask = [.portrait, .landscapeRight].map { [=10=] }
orientations1
工作正常,但 orientation2
产生以下错误:
Type of expression is ambiguous without more context
UIInterfaceOrientationMask
间接符合 ExpressibleByArrayLiteral
协议。 .map { [=19=] }
怎么可能改变数组的内容,我应该怎么做才能让它工作?
更新
好的,这就是我正在尝试做的事情。我正在学习 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({ [=13=].isOn }).map({ UIInterfaceOrientationMask(rawValue: UInt([=13=].tag)) }) // doesn't work
}
但是没用。我的 supportedInterfaceOrientations
看起来就像这样:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return orientations
}
我可以通过 insert()
方法为每个 UI 开关元素做到这一点,但我想了解是否可以通过映射以更优雅的方式完成。
Type of expression is ambiguous without more context
因为 Map
函数 returns 一个 array
值作为输出。因此,您需要像这样将推断类型更改为 array
以获得所需的 map
函数输出。
let orientations2: [UIInterfaceOrientationMask] = [.portrait, .landscapeRight].map { [=10=] }
在 Swift 中,文字是无类型的,它们的类型是根据上下文推断的。
在你的例子中,如果 Swift 推断数组文字的类型为 Array< UIInterfaceOrientationMask>
,你可以应用 .map{ [=12=] }
,但结果也变成 Array<UIInterfaceOrientationMask>
而不能转换为 UIInterfaceOrientationMask
。 (见下文。)
如果 Swift 将数组文字的类型推断为 UIInterfaceOrientationMask
,则 map
不可用。
因此,Swift 找不到与您的声明匹配的任何类型,这导致 Type of expression is ambiguous without more context
.
正如您在另一个线程的评论中所建议的那样,编译器使用 ExpressibleByArrayLiteral
根据上下文解释数组文字。并不意味着数组可以自动转换为符合ExpressibleByArrayLiteral
.
对于更新
如您所见,UIInterfaceOrientationMask
没有采用 Array
的常用初始化程序。所以使用 insert
是一种稳定的方式。稳定的代码比看似聪明但脆弱或难以阅读的代码更优雅。
如果你坚持使用看似聪明的代码,你可以这样写:
@IBAction func orientationSwitched(_ sender: UISwitch) {
orientations = orientationSwitches
.filter{[=10=].isOn}
.map{UIInterfaceOrientationMask(rawValue: UInt([=10=].tag))}
.reduce([]) {[=10=].union()}
}