我无法理解显式声明的String和隐式解包的可选字符串之间的区别。
例如,
如果我们显式初始化一个字符串,
let assumedString:String = "Test String"
print(assumedString)
给出输出
"Test String"
"Test String\n"
在操场上。
同样,如果我们隐式解开像这样的可选字符串,
let assumedString:String! = "Test String"
print(assumedString)
给出相同的输出
"Test String"
"Test String\n"
而且一旦我们使用'!'在初始化时,它的值不能为零。那么我们可以使用显式类型吗?
那么为什么我们必须使用'!'的概念(隐式展开可选字符串)。
请解释使用'!'的区别或用法如果可能,请使用代码示例。
答案 0 :(得分:2)
在您的示例中,您只使用let
个常量。使用let
常量,您几乎看不到两者之间的差异。情况发生了变化。
如您所知,必须将类中的所有属性初始化为初始值设定项中的某个值。可选属性是此规则的一个例外。它们默认为nil
,即没有值。
我经常使用隐含的解包选项是当我有一个存储视图高度或任何UI相关的属性时。我总是将它们声明为隐式解包的选项。 e.g。
var myViewsHeight: CGFloat!
override func viewDidLoad() {
myViewsHeight = self.view.viewWithTag(1).frame.height
}
您显然无法在init
中初始化该变量,因为在init
,视图尚未布局!没有办法知道视图的高度。你使它成为一个隐含的解包可选项,因为你知道将在viewDidLoad
中初始化。这样做的另一个好处是它可以使跟踪错误更容易。说你的应用程序崩溃了,因为如果viewDidLoad
中发生了某些事情并且未执行初始化myViewsHeight
的行,你会立即知道因为你的应用程序崩溃了!
您还会看到所有IBOutlet
都是隐含的解包选项,出于同样的原因 - 无法在init
分配视图。
答案 1 :(得分:0)
let assumedString:String = "Test String"
意味着你只需定义一个字符串常量,但是当你写
时let assumedString:String! = "Test String"
表示您声明了一个可选类型的字符串。因此,它可能包含或不包含值。但是在这里你是在声明字符串时初始化的。所以,如果你打印两者都会给出相同的输出。欲了解更多信息,请访问以下链接