在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<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 here
print(str.count)
但是在所有其他str
可以作为强选项进行类型检查的情况下,它将是:
// `x` is inferred to be a `String?` (because we really are assigning a `String?`)
let x = str
let 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!
将具有typeT
或typeT?
。
关于字符串插值,在后台,编译器使用_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
。
我有一个在生产模式下运行的rails应用程序,但是今天当一个用户试图保存记录时突然出现了这个错误。 谢谢
我是C#的新手,我有一些Java方面的基础知识,但我不能让这段代码正常运行。 它只是一个基本的计算器,但当我运行程序时,VS2008给了我这个错误: 我做了几乎相同的程序,但在Java使用的是JSwing,它运行得非常好。 下面是C#的形式: 会有什么问题?有没有办法解决? PS:我也试过 但没有奏效。
我试图上传csv到我的mysql数据库使用jooq,但我得到以下错误。我在网上尝试了各种建议的解决方案,但都没能解决 我如何将csv上传到jooq 我确保文件在utf-8中,但是当有UTF-8字符记录时,无法保存在DB中并抛出上述错误。我确保使用 前端ajax: 我正在通过java rest从前端读取文件 并在传递给jooq之前在本地系统中递归写入文件 我将DB设置为接受utf-8,并进行了验证
在尝试向列添加一些内容后,我得到了 问题出在哪里?
嘿,我用oracle DB和Iron Python一起使用,但我在使用包含字符“‘”的字符串时遇到了麻烦,就像Mc'Donalds中一样。(我知道它在寻找结尾')从用户输入中接受字符串,我想按原样将其添加到我的数据库中,这意味着不省略或更改任何字符。我怎么做?
问题内容: 我有一个包含数字的字符串列表,但找不到找到对它们进行排序的好方法。 例如,我得到这样的东西: 用的方法。 我知道我可能需要以某种方式提取数字,然后对列表进行排序,但是我不知道如何以最简单的方式进行操作。 问题答案: 也许您正在寻找人工排序(也称为自然排序): 产量 PS。我已经更改了答案,以使用Toothy的自然排序实现(在此处发表评论),因为它比我的原始答案快得多。 如果您希望使用浮