Swift 3不正确的字符串插值,带有隐式展开的Optionals

Swift 3不正确的字符串插值,带有隐式展开的Optionals,第1张

Swift 3不正确的字符串插值,带有隐式展开的Optionals

根据SE-0054,

ImplicitlyUnwrappedOptional<T>
不再是唯一类型;只有
Optional<T>
现在。

声明仍然可以被注释为隐含的未包装的可选内容

T!
,但这只是添加一个隐藏的属性来通知编译器,在需要他们的未包装类型的上下文中,它们的值可能被强制包装
T
;
他们的实际类型是现在
T?

因此,您可以想到以下声明:

var str: String!

实际看起来像这样:

@_implicitlyUnwrapped // this attribute name is fictitious var str: String?

只有编译器可以看到此

@_implicitlyUnwrapped
属性,但是它允许的是在
str
需要a
String
(其未包装类型)的上下文中隐式展开的值:

// `str` cannot be type-checked as a strong optional, so the compiler will// implicitly force unwrap it (causing a crash in this case)let x: String = str// We're accessing a member on the unwrapped type of `str`, so it'll also be// implicitly force unwrapped hereprint(str.count)

但是在所有其他

str
可以作为强选项进行类型检查的情况下,它将是:

// `x` is inferred to be a `String?` (because we really are assigning a `String?`)let x = strlet y: Any = str // `str` is implicitly coerced from `String?` to `Any`print(str) // Same as the previous example, as `print` takes an `Any` parameter.

而且,与强制展开相比,编译器将始终更喜欢将其视为此类。

如提案所述(强调我的意思):

如果 可以使用强壮的可选类型 对表达式 进行显式类型检查,则它将为 。但是,如果需要,类型检查器将转为强制使用可选。此行为
的结果是,引用声明为的值的任何表达式的结果

T!
将具有type
T
或type
T?

关于字符串插值,在后台,编译器使用

_ExpressibleByStringInterpolation
协议中的此初始化程序来评估字符串插值段:

/// Creates an instance containing the appropriate representation for the/// given value.////// Do not call this initializer directly. It is used by the compiler for/// each string interpolation segment when you use string interpolation. For/// example://////     let s = "(5) x (2) = (5 * 2)"///     print(s)///     // Prints "5 x 2 = 10"////// This initializer is called five times when processing the string literal/// in the example above; once each for the following: the integer `5`, the/// string `" x "`, the integer `2`, the string `" = "`, and the result of/// the expression `5 * 2`.////// - Parameter expr: The expression to represent.init<T>(stringInterpolationSegment expr: T)

因此,当您的代码隐式调用时:

var str: String!str = "Hello"print("The following should not be printed as an optional: (str)")

由于

str
的实际类型是
String?
,因此默认情况下,编译器将推断通用占位符
T
为。因此,
str
不会强行解开的值,您最终将看到可选内容的描述。

如果希望在字符串插值中使用时将IUO强制展开,则可以简单地使用force unwrap运算符

!

var str: String!str = "Hello"print("The following should not be printed as an optional: (str!)")

或者,您可以强制使用其非可选类型(在这种情况下为

String
),以强制编译器为您隐式强制对其进行解包:

print("The following should not be printed as an optional: (str as String)")

如果

str
为,这两个当然都会崩溃
nil



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5642179.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存