Sử dụng nhiều let-as trong câu lệnh if trong Swift


144

Tôi đang hủy bỏ hai giá trị từ một từ điển và trước khi sử dụng chúng, tôi phải bỏ chúng và kiểm tra đúng loại. Đây là những gì tôi nghĩ ra:

var latitude : AnyObject! = imageDictionary["latitude"]
var longitude : AnyObject! = imageDictionary["longitude"]

if let latitudeDouble = latitude as? Double  {
   if let longitudeDouble = longitude as? Double {
       // do stuff here
   }
}

Nhưng tôi muốn gói hai cái nếu để truy vấn thành một. Vì vậy, nó sẽ một cái gì đó như thế:

if let latitudeDouble = latitude as? Double, longitudeDouble = longitude as? Double {
    // do stuff here
}

Cú pháp đó không hoạt động, vì vậy tôi đã tự hỏi liệu có một cách hay để làm điều đó.


1
có thể trùng lặp với việc hủy ghép nhiều tùy chọn trong câu lệnh if
Jack

Có thể có một cách để sử dụng một câu lệnh chuyển đổi để mô hình khớp với các loại. Hãy xem Tài liệu :
lomokat

1
có thể trùng lặp với việc sử dụng "if let ..." với nhiều biểu thức
rickster

Câu trả lời:


305

Cập nhật cho Swift 3:

Phần sau sẽ hoạt động trong Swift 3:

if let latitudeDouble = latitude as? Double, let longitudeDouble = longitude as? Double {
    // latitudeDouble and longitudeDouble are non-optional in here
}

Chỉ cần nhớ rằng nếu một trong các ràng buộc tùy chọn đã thử thất bại, mã bên trong if-letkhối sẽ không được thực thi.

Lưu ý: các mệnh đề không phải là mệnh đề 'hãy', bạn có thể có bất kỳ chuỗi kiểm tra boolean nào được phân tách bằng dấu phẩy.

Ví dụ:

if let latitudeDouble = latitude as? Double, importantThing == true {
    // latitudeDouble is non-optional in here and importantThing is true
}

Swift 1,2:

Apple có thể đã đọc câu hỏi của bạn, bởi vì mã hy vọng của bạn sẽ biên dịch đúng trong Swift 1.2 (trong phiên bản beta ngày hôm nay):

if let latitudeDouble = latitude as? Double, longitudeDouble = longitude as? Double {
    // do stuff here
}

Swift 1.1 trở về trước:

Đây là tin tốt - bạn hoàn toàn có thể làm điều này. Một câu lệnh chuyển đổi trên một tuple của hai giá trị của bạn có thể sử dụng khớp mẫu để truyền cả hai giá trị đó Doublecùng một lúc:

var latitude: Any! = imageDictionary["latitude"]
var longitude: Any! = imageDictionary["longitude"]

switch (latitude, longitude) {
case let (lat as Double, long as Double):
    println("lat: \(lat), long: \(long)")
default:
    println("Couldn't understand latitude or longitude as Double")
}

Cập nhật: Phiên bản mã này hiện đang hoạt động đúng.


nó hoạt động với tôi trong 6.1.1, @AaronBratcher tại sao không cho bạn?
Daniel Gomez Rico

1
Trong Swift 1.2, giờ đây bạn có thể thực hiện việc này trong một dòng: stackoverflow.com/a/28418847/1698576
smithclay

Trong mã của bạn, bạn có 2 tùy chọn được mở ra. Có phải nó được sử dụng luôn như vậy? Tôi có mã khó hiểu khác nhau. if let app = UIApplication.sharedApplication().delegate as? AppDelegate, let window = app.window {...}. Là thứ 2 let cũng tùy chọn ràng buộc? Ý tôi applà không còn là một lựa chọn. đúng?
Mật ong

1
Nó là. appkhông còn là một tùy chọn, nhưng thuộc tính của nó windowlà (loại của nó UIWindow?), vì vậy đó là những gì bạn đang mở.
Nate Cook

7

Với Swift 3, bạn có thể sử dụng chuỗi tùy chọn, câu lệnh chuyển đổi hoặc mẫu tùy chọn để giải quyết vấn đề của mình.


1. Sử dụng if let(ràng buộc tùy chọn / chuỗi tùy chọn)

Các Swift Lập trình Ngôn ngữ nói về chaining tùy chọn:

Nhiều truy vấn có thể được nối lại với nhau và toàn bộ chuỗi không thành công nếu bất kỳ liên kết nào trong chuỗi không.

Do đó, trong trường hợp đơn giản nhất, bạn có thể sử dụng mẫu sau để sử dụng nhiều truy vấn trong hoạt động chuỗi tùy chọn của mình:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if let latitude = latitude as? Double, let longitude = longitude as? Double {
    print(latitude, longitude)
}

// prints: 2.0 10.0

2. Sử dụng bộ dữ liệu và ràng buộc giá trị trong câu lệnh chuyển đổi

Thay thế cho một chuỗi tùy chọn đơn giản, câu lệnh switch có thể cung cấp một giải pháp chi tiết tốt khi được sử dụng với các bộ dữ liệu và ràng buộc giá trị:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

switch (latitude, longitude) {
case let (Optional.some(latitude as Double), Optional.some(longitude as Double)):
    print(latitude, longitude)
default:
    break
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

switch (latitude, longitude) {
case let (latitude as Double, longitude as Double):
    print(latitude, longitude)
default:
    break
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

switch (latitude as? Double, longitude as? Double) {
case let (.some(latitude), .some(longitude)):
    print(latitude, longitude)
default:
    break
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

switch (latitude as? Double, longitude as? Double) {
case let (latitude?, longitude?):
    print(latitude, longitude)
default:
    break
}

// prints: 2.0 10.0

3. Sử dụng bộ dữ liệu với if case(mẫu tùy chọn)

if case( mẫu tùy chọn ) cung cấp một cách thuận tiện để mở các giá trị của phép liệt kê tùy chọn. Bạn có thể sử dụng nó với các bộ dữ liệu để thực hiện một số chuỗi tùy chọn với nhiều truy vấn:

let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if case let (.some(latitude as Double), .some(longitude as Double)) = (latitude, longitude) {
    print(latitude, longitude)
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if case let (latitude as Double, longitude as Double) = (latitude, longitude) {
    print(latitude, longitude)
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if case let (.some(latitude), .some(longitude)) = (latitude as? Double, longitude as? Double) {
    print(latitude, longitude)
}

// prints: 2.0 10.0
let dict = ["latitude": 2.0 as AnyObject?, "longitude": 10.0 as AnyObject?]
let latitude = dict["latitude"]
let longitude = dict["longitude"]

if case let (latitude?, longitude?) = (latitude as? Double, longitude as? Double) {
    print(latitude, longitude)
}

// prints: 2.0 10.0

5

Swift 3.0

if let latitudeDouble = latitude as? Double, let longitudeDouble = longitude as? Double {
    // do stuff here
}

4
Bạn nên đề xuất một chỉnh sửa cho câu trả lời được chấp nhận, đừng thêm một câu trả lời chất lượng thấp hơn.
jervine10
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.