2015-11-12 12 views
31

Tôi đã nhận thấy hành vi nhanh chóng kỳ lạ, bởi vì trong biến màu sắc ý kiến ​​của tôi không nên bị ép buộc trong trường hợp chuyển đổi được viết dưới đây, nhưng không có trình biên dịch unwrapping cho tôi thấy một thông báo lỗi.Tại sao buộc tháo dỡ là cần thiết trong trường hợp enum và chuyển đổi?

enum Colours: Int { 
case Red = 0, White, Black 
} 

var colours: Colours! 
colours = .Red 

switch colours! { // <-- why I have to unwrap colours? As you can see colours are declared as '!' 
case .Red: break 
default: break 
} 

nếu màu sắc biến không phải là trình biên dịch nào cho thấy tôi rằng lỗi: enter image description here

theo ý kiến ​​của tôi nó là mâu thuẫn nhanh chóng, không ai có một số ý tưởng?

Trả lời

32

Khi được sử dụng trong một tuyên bố switch, thậm chí ngầm tháo optionals là không tự động nào. (Một lý do có thể là bạn không thể phù hợp với họ chống lại nil khác.)

Vì vậy, bạn phải unwrap (hoặc buộc với colours! đó sẽ sụp đổ nếu colours == nil, hoặc với tùy chọn ràng buộc), hoặc - cách khác - trận đấu với .Red? mà là một phím tắt cho .Some(.Red):

var colours: Colours! 

switch colours { 
case .Red?: 
    break // colours is .Red 
default: 
    break // colours is .White, .Black or nil 
} 

cùng giữ cho các biểu mẫu khớp khác, ví dụ như

if case .Red? = colours { 
    // colours is .Red 
} else { 
    // colours is .White, .Black or nil 
} 

Ngoài này không có gì để làm với các loại điều tra, chỉ với ngầm optionals quà nào trong một mô hình:

let x : Int! = 1 

switch x { 
case nil: 
    break // x is nil 
case 1?: 
    break // x is 1 
default: 
    break // x is some other number 
} 
+0

Một vài trong số các 'colours' của bạn là' colors' ;-) – vacawama

+0

@vacawama: Đổ lỗi cho tự động sửa lỗi :) –

+0

Có! Autocorrection cũng đã sửa lại bình luận của tôi. Đổ lỗi có thể thực sự thuộc về Noah Webster. :-) – vacawama

2

Điều này là do bạn tạo colours biến như loại tùy chọn. Nếu bạn làm như thế này:

var colours: Colours 
colours = .Red 

bạn sẽ không phải unwrappe giá trị này

Nếu chúng ta nhìn vào những gì các loại tùy chọn là, chúng ta sẽ thấy rằng đây là enum như:

enum Optional<T> { 
    case Some(T) 
    case None 
} 

Và nó có thể là Some Kiểu như Int ví dụ hoặc None và trong trường hợp này, nó có giá trị bằng 0.

Khi bạn thực hiện điều này:

var colours: Colours! 

bạn trực tiếp được chỉ định bởi ! rằng đây không phải là Colours loại nhưng đây là loại enum ImplicitlyUnwrappedOptional<Colours>. Tại thời điểm sáng tạo, nó sẽ là Some<Colours> nếu bằng giá trị đó nhưng với số này !, bạn có nó là enum ImplicitlyUnwrappedOptional<Colours> và trong một số thời điểm tiếp theo, nó sẽ là None. Đó là lý do tại sao bạn phải sử dụng ! trong switch:

giá trị colours của bạn là ImplicitlyUnwrappedOptional<Colours> loại và nó có thể là Colours hoặc nil và bạn phải chỉ ra trực tiếp rằng đây là Colours loại trong `switch``.

+1

Ông có thể cung cấp một số tài liệu cho thấy rằng tuyên bố một biến với ' 'làm cho nó không bắt buộc ? – Arc676

+0

@ Arc676 tôi chỉnh sửa câu trả lời –

+1

'màu sắc' có loại' Ngụ ý Không được hấp thụTùy chọn ', không phải 'Tùy chọn '. –

1

Thay vì sử dụng:

var colours: Colours! 
colours = .Red 

Đơn giản chỉ cần sử dụng

var colours = Colours.Red 

Điều đó sẽ làm các trick.

+1

Nhưng tôi muốn có biến màu tùy chọn. Nó sẽ hoạt động mà không có '!' theo ý kiến ​​của tôi. – Robert

+2

@roher Khai báo một biến kiểu enum là tùy chọn không phải là rất hữu ích vì một enum được thiết kế để có một trạng thái xác định. Sử dụng trạng thái .'Không' hoặc tương tự thay vì tùy chọn. – vadian

Các vấn đề liên quan