Swift 4可选数组非空检查及if let/guard用法疑问
Hey there! Coming from Java to Swift can feel a bit tricky with optionals at first, but let's break this down step by step to get you comfortable.
First: Replicating Your Java Check in Swift
Your Java code if(listCountries != null && listCountries.size()>0) translates neatly to Swift with a couple of safe, idiomatic approaches:
Option 1: Using if let (for in-block usage)
This is perfect when you only need to work with the non-nil, non-empty array inside a specific code block:
override func viewDidLoad() { super.viewDidLoad() if let countries = listCountries, !countries.isEmpty { // Here, `countries` is a non-optional [Countries] array, guaranteed to be non-empty // You can safely use it — e.g., loop through items, access indices, etc. for country in countries { print(country.name) } } else { // Handle the case where listCountries is nil OR empty print("No countries available") } }
The comma here acts like Java's && — it first unwraps listCountries into countries, then checks if countries isn't empty. Both conditions need to pass to enter the first block.
Option 2: Using guard let (for early exit, cleaner code)
If you want to avoid nested code blocks and exit early if the array is nil/empty, guard let is your friend. It keeps your main logic flat and readable:
override func viewDidLoad() { super.viewDidLoad() guard let countries = listCountries, !countries.isEmpty else { // If either condition fails (nil or empty), run this code and exit the method print("No countries to process") return } // From here on, `countries` is available as a non-optional, non-empty array // No nesting needed — your main logic lives here setupCountryList(countries) } func setupCountryList(_ countries: [Countries]) { // Use the array safely }
Clearing Up if let, guard let, and Optional Unwrapping
Let's break down these tools so you know when to use each:
What Are Optionals, Anyway?
Swift's T? (like your [Countries]?) is Swift's way of marking a value that might be "missing" (similar to Java's null, but enforced by the compiler to prevent accidental crashes). Unwrapping is the process of getting the actual non-optional value out of the optional wrapper.
1. if let — Bind and Use Locally
- Use case: You only need the unwrapped value inside a specific code block.
- It creates a constant (or variable, with
if var) that's only accessible inside theifblock. - Example:
let optionalUsername: String? = "SwiftNewbie123" if let username = optionalUsername { print("Welcome back, \(username)!") // `username` is a non-optional String here } else { print("Please log in.") }
2. guard let — Bind and Use Globally (in the current scope)
- Use case: You need the unwrapped value for the rest of your method/function, and want to exit early if the optional is nil.
- It avoids "pyramid of doom" nested
ifblocks, keeping your code linear. - The bound constant/variable is available after the
guardstatement, not just inside a block. - Example:
func submitForm(optionalEmail: String?) { guard let email = optionalEmail else { print("Please enter an email address") return // Exit the function early } // `email` is usable here for the rest of the function sendEmail(to: email) }
3. Forced Unwrapping (!) — Use Sparingly!
This is like Java assuming an object isn't null — it will crash your app if the optional is nil. Only use this if you are 100% certain the optional has a value (e.g., you just assigned it):
var optionalScore: Int? = 95 let score = optionalScore! // Safe here, since we just set it to 95 // But if optionalScore was nil, this line would crash
4. Optional Chaining (?.) — Safe Property/Method Calls
If you just need to access a property or call a method on an optional, use optional chaining. If the optional is nil, the result will be nil instead of crashing:
let countryCount = listCountries?.count // `countryCount` is Int? — nil if listCountries is nil, otherwise the actual count
Quick Recap for Your Scenario
- To check if your optional array is non-nil and non-empty: Use
if let countries = listCountries, !countries.isEmptyorguard let countries = listCountries, !countries.isEmpty else { ... } - Prefer
guard letwhen you want to exit early and keep your main logic un-nested - Avoid forced unwrapping (
!) unless you're absolutely sure the optional isn't nil
内容的提问来源于stack exchange,提问作者Android teem

