2015-10-19 21 views
5

Tôi đang cố gắng để hiểu làm thế nào để cho nó hoạt động:Swift Tùy chọn kiểu: làm thế nào .None == nil làm việc

1> func returnNone() -> String? { return .None } 
    2> returnNone() == nil 
$R0: Bool = true 
    3> returnNone() == .None 
$R1: Bool = true 

Tại sao .None bằng nil.

tôi không thấy bất cứ điều gì về nó trong định nghĩa enum:

public enum Optional<Wrapped> : _Reflectable, NilLiteralConvertible { 
    case None 
    case Some(Wrapped) 
    /// Construct a `nil` instance. 
    public init() 
    /// Construct a non-`nil` instance that stores `some`. 
    public init(_ some: Wrapped) 
    /// If `self == nil`, returns `nil`. Otherwise, returns `f(self!)`. 
    @warn_unused_result 
    @rethrows public func map<U>(@noescape f: (Wrapped) throws -> U) rethrows -> U? 
    /// Returns `nil` if `self` is nil, `f(self!)` otherwise. 
    @warn_unused_result 
    @rethrows public func flatMap<U>(@noescape f: (Wrapped) throws -> U?) rethrows -> U? 
    /// Create an instance initialized with `nil`. 
    public init(nilLiteral:()) 
} 

Trả lời

12

enum Optional phù hợp với NilLiteralConvertible giao thức, có nghĩa là nó có thể được khởi tạo với "nil" theo nghĩa đen. Kết quả là Optional<T>.None trong đó trình giữ chỗ loại T phải được suy ra từ ngữ cảnh.

Như một ví dụ,

let n = nil // type of expression is ambiguous without more context 

không biên dịch, nhưng

let n : Int? = nil 

làm, và kết quả là Optional<Int>.None.

Bây giờ optionals thể nói chung không thể so sánh nếu tiềm ẩn loại không phải là Equatable:

struct ABC { } 

let a1 : ABC? = ABC() 
let a2 : ABC? = ABC() 

if a1 == a2 { } // binary operator '==' cannot be applied to two 'ABC?' operands 

và thậm chí điều này không biên dịch:

if a1 == Optional<ABC>.None { } // binary operator '==' cannot be applied to two 'ABC?' operands 

Nhưng điều này biên dịch:

if a1 == nil { } 

Sử dụng toán tử

public func ==<T>(lhs: T?, rhs: _OptionalNilComparisonType) -> Bool 

trong đó _OptionalNilComparisonType không được ghi chép chính thức. Trong https://github.com/andelf/Defines-Swift/blob/master/Swift.swift định nghĩa có thể được tìm thấy như (được tìm thấy bởi @rintaro và @Arsen, xem ý kiến):

struct _OptionalNilComparisonType : NilLiteralConvertible { 
    init(nilLiteral:()) 
} 

Điều này cho phép so sánh của bất kỳ loại tùy chọn với "con số không", bất kể loại cơ bản là Equatable hay không.

Tóm lại - trong bối cảnh Optional - nil có thể được coi là lối tắt đến .None, nhưng loại bê tông phải được suy ra từ ngữ cảnh. Có một toán tử chuyên dụng == để so sánh với "nil".

+0

@Cosyn: Nếu bạn định nghĩa 'enum Op ' của riêng bạn thì bạn cũng phải xác định toán tử '==' cho loại đó. Nhưng bạn nói đúng, câu cuối cùng là gây hiểu nhầm. –

+0

@MartinR @Cosyn vì vậy những gì. Câu trả lời là ở đâu đó táo định nghĩa phương pháp '==' để so sánh Các loại tùy chọn? – Arsen

+0

Tốt, sau khi tôi thêm ==, sau đó nó hoạt động – Cosyn

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