Int与隐式解包可选Int(Int!)的区别是什么?
ClassName! and ClassName in Swift Hey there! Let's break down this common Swift confusion clearly—especially since you noticed no immediate difference when removing the ! from your property declaration.
First, plain ClassName
When you declare a property like var number: Int, you're defining a non-optional type. Here's what that means:
- It must have a value assigned before the class instance is fully initialized (either directly in the initializer or via a default value).
- You can never assign
nilto it—the compiler will throw an error if you even try. - When you access it, no unwrapping is needed because the compiler guarantees it holds a valid value.
Now, ClassName! (Implicitly Unwrapped Optional)
var _number: Int! is an implicitly unwrapped optional. It's a special kind of optional that balances flexibility and convenience:
- Under the hood, it's still an optional—so it can be
nilinitially. - The key perk: you don't need to use
?(optional chaining) or!(force unwrapping) every time you access it. Swift automatically unwraps it for you. - The big risk: if you access it when it's
nil, your app will crash immediately—just like if you force-unwrapped a regular optional with!.
Why would you ever use ClassName!?
This type shines for properties you know will have a value before they're used, but can't assign during initialization. Common examples:
- IBOutlets in UIKit/SwiftUI: Interface Builder sets these values after the class initializes, so we use
@IBOutlet weak var titleLabel: UILabel!to skip repetitive unwrapping. - Properties initialized later in a setup method (e.g., a
configure()call that runs right after the class is created).
Why didn't you see a difference when removing the !?
If your test code always assigned a value to _number before accessing it, you wouldn't notice a change. But edge cases reveal the gap:
- If you use
var _number: Intwithout assigning it in the initializer, the compiler will throw an error immediately (it enforces non-optional properties are initialized). - If you use
var _number: Int!and forget to assign it before accessing, the compiler won't warn you—but your app will crash at runtime.
A quick best practice
Stick to implicitly unwrapped optionals only when you have no other choice. Prefer:
- Plain
ClassNamewhen you can guarantee the value exists at initialization. - Regular optionals (
ClassName?) when the value might benil—this forces you to handle thenilcase safely with optional binding or chaining.
内容的提问来源于stack exchange,提问作者Gal Shahar

