为什么 String 会隐式变成 String!在 Swift

Why does String implicitly become String! in Swift

我昨天收到来自 Xcode 的编译错误,说

Binary operator '&&' cannot be applied to two Bool operands [1]

if text != nil && presentingViewController != nil {
    ...
}

text 之前定义为

var text: String = "" {
    didSet {
        ...
    }
}

presentingViewController来自UIViewController,也就是superclass.

我的一个朋友告诉我这是由 String!text 引起的,通过更改

解决了这个问题
var text: String

var text: String?

但是,为什么我明确定义的String变成了String!,我仍然很困惑。谁能提供有关此隐式转换的任何详细信息?

[1] 这个编译错误没有意义,这个问题不是 .

的重复

您明确定义的 String 不是 String! 是... String。就这么简单 ;-)

String! 是一个 隐式展开的 Optional<String>

String? 是一个 Optional<String>

Optional<T>表示它可以是TNothing类型的值(没有什么可以与nil相比)。

因此当您声明时:

var text = ""

您声明了一个实际的字符串,它不能是 nil。这就是编译器抱怨的原因:a String cannot be Nothing。把它想象成比较 StringCGFloat ...编译器会抱怨。

因为 String! 是一个 Optional<String>,所以它可以与 nil 进行比较。 ! 只是你声明你绝对确定它不是 Nothing 这样你就可以使用 text 而无需 展开 它的实际值。

顺便说一句,不要将 空字符串 (即:"")与 Nothing 混淆。 var text = "" 是一个实际的 String 只是空的,它不能与 Nothing

相比较

希望这对您有所帮助。

你的朋友肯定没有解决你的问题,他只是掩饰了而已。

您声明了一个字符串类型的实例变量。文本将始终是一个字符串。它永远不可能为零。询问 "text != nil" 是没有意义的,因为它不能为零。它甚至无法编译,因为一个始终为 nil 的字符串甚至无法检查是否为 nil。

你的朋友建议使用字符串?或字符串!那在你的情况下完全是胡说八道。您有保证始终为字符串的文本。相反,您将其更改为可能是 String 或 nil 的文本。这对你没有任何帮助。是的,现在你可以问它是否为零。以前,你甚至不必问。

您的问题与 swift 中所谓的 "optionals" 有关。

在 Objective-C 中,您可以引用 NSString,它可以指向 NSString 实例 - 或者指向 nil。在 swift 这是不一样的!

"regular" swift 中的字符串永远不能为 nil。只有 "optional" 字符串可以为 nil。这是它在 swift 代码中的样子:

var myRegularString  : String      // this can never be nil, can't compare to nil
var myOptionalString : String?     // this can be nil (note the ?)

您有一个 "regular" 字符串。因此,当您尝试将其与 nil 进行比较时,编译器会报错。

这里解释了选项:Swift Programming Language/Basics/Optionals