Swift 3不正确的字符串插值,带隐式解包的可选项

前端之家收集整理的这篇文章主要介绍了Swift 3不正确的字符串插值,带隐式解包的可选项前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
为什么在Swift 3中使用字符串插值时,隐式解包的可选性不会解包?

例:
在操场中运行以下代码

var str: String!
str = "Hello"

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

产生此输出

The following should not be printed as an optional: Optional("Hello")

当然,我可以连接字符串与运算符,但我使用字符串插值几乎无处不在我的应用程序,现在不再工作,由于这个(错误?)。

这是甚至是一个错误或者他们有意改变这对Swift 3?

根据 SE-0054,ImplicitlyUnwrappedOptional不再是一个不同的类型。相反,它现在是一个常规 Optional相同的类型 – 它只是有一个属性,允许编译器强制解开它的情况下,不能将类型检查为一个。

正如建议所说(强调我):

If the expression can be explicitly type checked with a strong optional type,it will be. However,the type checker will fall back to forcing the optional if necessary. The effect of this behavior is that the result of any expression that refers to a value declared as T! will either have type T or type T?.

这意味着,当涉及到类型推断时,编译器将总是倾向于将一个隐式解包的可选项作为一个Optional,而不是强制解开它。但是,当提供显式类型注释时,此行为将被覆盖。

当涉及字符串插值时,编译器使用此初始化器从_ExpressibleByStringInterpolation protocol为了评估字符串插值段:

/// 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)

由于此初始化器使用generic参数(没有显式类型注释),因此编译器能够将隐式解包的可选输入的参数T推断为类型Optional,因此意味着不会强制解包。

相反,如果你采用例如print(),它接受一个Any参数(一个显式的,虽然是抽象类型的注释),编译器将不能推断一个IUO输入类型为Optional,因此它将隐式强制解包。

如果您希望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是零。

猜你在找的Swift相关文章