2017-08-06 22 views
0

我這個實驗:爲什麼映射數組本身可以表示出錯?

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

orientations1工作正常,但orientation2產生以下錯誤:

Type of expression is ambiguous without more context

UIInterfaceOrientationMask間接符合ExpressibleByArrayLiteral協議。 .map { $0 }怎麼可能改變數組的內容,我應該怎麼做才能使它工作?

UPDATE

好了,這裏就是我想要做的事。我正在學習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 
} 

我能夠通過每個UI開關組件insert()的方法來做到這一點,但我想學習,如果能在更優雅的方式來完成,通過映射。

+0

'UIInterfaceOrientationMask'是* OptionSet *,而不是*數組*。所以,即使你可以用數組字面值初始化它,你也不能爲它分配一個數組,這是'map'返回的值。 – vacawama

+0

可怕,但作品:'var orientationations2:UIInterfaceOrientationMask = [UIInterfaceOrientationMask.portrait,.landscapeRight] .map {$ 0} .reduce(UIInterfaceOrientationMask()){var result = $ 0; result.insert($ 1);返回結果}' – vacawama

+0

@vacawama,你可以使用'union','UIInterfaceOrientationMask()'可以用'[]'替換。 – OOPer

回答

1

在Swift中,文字是無類型的,它們的類型根據上下文來推斷。

在你的情況,如果斯威夫特推斷數組文本作爲Array< UIInterfaceOrientationMask>的類型,你可以申請.map{ $0 },但結果也變得Array<UIInterfaceOrientationMask>,不能轉化爲UIInterfaceOrientationMask。 (請參閱下面的內容。)

如果Swift推斷出數組文字的類型爲UIInterfaceOrientationMask,則map不可用。

因此,Swift找不到與您的聲明相匹配的任何類型,這會導致Type of expression is ambiguous without more context


正如你在另一個線程的意見被提出,ExpressibleByArrayLiteral使用編譯器根據上下文解釋數組文本。這並不意味着陣列可以自動轉換爲符合ExpressibleByArrayLiteral的類型。


對於UPDATE

正如你看到的,UIInterfaceOrientationMask沒有通常的初始化服用Array。所以使用insert是一個穩定的方法。穩定的代碼比看起來聰明但脆弱或難以閱讀的代碼更優雅。

如果你堅持要用看似聰明代碼,你可以寫這樣的事情:

@IBAction func orientationSwitched(_ sender: UISwitch) { 
    orientations = orientationSwitches 
     .filter{$0.isOn} 
     .map{UIInterfaceOrientationMask(rawValue: UInt($0.tag))} 
     .reduce([]) {$0.union($1)} 
} 
+0

有什麼我可以做的嗎?我想通過它們的'tag'屬性將一些UI元素的數組映射到'UIInterfaceOrientationMask'類型。換句話說,我的4個UI元素中的每一個代表不同的設備方向。 –

+0

@RoboRobok,你不知道你真的想做什麼。添加一些更具體和具體的示例代碼。 – OOPer

+0

我更新了問題。 –

1

Type of expression is ambiguous without more context

因爲Map函數返回值爲array作爲輸出。因此,您需要將推斷類型更改爲array,以得到所需的map函數輸出。

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

'UIInterfaceOrientationMask'符合'ExpressibleByArrayLiteral',可以用數組表示。我需要'UIInterfaceOrientationMask'類型,而不是'[UIInterfaceOrientationMask]'。 –

+0

@RoboRobok,你的觀點是有道理的。但我想如果你只是需要解決這個錯誤。所以你可以將推斷的類型定義爲一個數組。 –

+0

我收錄了一些我想要做的更具體的描述。 –