使用Swift字符串可选链接

Ste*_*aub 14 string optional swift

使用可选链接,如果我有一个Swift变量

var s: String?
Run Code Online (Sandbox Code Playgroud)

s可能包含nil,或者包含在Optional中的String.所以,我尝试了这个来得到它的长度:

let count = s?.characters?.count ?? 0
Run Code Online (Sandbox Code Playgroud)

但是,编译器想要这样:

let count = s?.characters.count ?? 0
Run Code Online (Sandbox Code Playgroud)

我对可选链接的理解是,一旦你开始使用?.虚线表达式,其余的属性都是可选的,通常由?.,而不是..

所以,我进一步挖了一下,在操场上试了一下:

var s: String? = "Foo"
print(s?.characters)
// Output: Optional(Swift.String.CharacterView(_core: Swift._StringCore(_baseAddress: 0x00000001145e893f, _countAndFlags: 3, _owner: nil)))
Run Code Online (Sandbox Code Playgroud)

结果表明s?.characters确实是一个Optional实例,表明s?.characters.count应该是非法的.

有人能帮我理解这种状况吗?

Abi*_*ern 5

当你说:

我对可选链接的理解是,一旦你开始使用?.虚线表达式,其余的属性都是可选的,通常由?.,而不是..

我会说你几乎就在那里.

并不是所有属性都是可选的,原始调用是可选的,因此看起来其他属性是可选的.

characters不是可选属性,也不是count,但是您调用它的值是可选的.如果有值,那么characterscount属性将返回一个值; 否则,nil退回.正因为如此,s?.characters.count返回的结果是Int?.

如果其中一个属性是可选的,那么您需要添加?它,但是,在您的情况下,它们不是.所以你没有.


编辑以下评论

来自评论:

我还觉得奇怪,都s?.characters.count(s?.characters)?.count编译,但(s?.characters).count没有.为什么第一个和最后一个表达式之间存在差异?

我会尝试在这里回答它,其中有更多的空间而不是评论字段:

s?.characters.count
Run Code Online (Sandbox Code Playgroud)

如果s是nil,则返回整个表达式nil,否则返回Int.所以返回类型是Int?.

(s?.characters).count // Won’t compile
Run Code Online (Sandbox Code Playgroud)

打破下来:如果snil的话(s?.characters)就是nil,所以我们不能把count它.

为了调用count属性(s?.characters),表达式需要可选地解包,即写为:

(s?.characters)?.count
Run Code Online (Sandbox Code Playgroud)

编辑进一步添加

我能解释的最好的方法是使用这个操场代码:

let s: String? = "hello"

s?.characters.count
(s?.characters)?.count
(s)?.characters.count
((s)?.characters)?.count

// s?.characters.count
func method1(s: String?) -> Int? {
    guard let s = s else { return nil }

    return s.characters.count
}

// (s?.characters).count
func method2(s: String?) -> Int? {
    guard let c = s?.characters else { return nil }

    return c.count
}

method1(s)
method2(s)
Run Code Online (Sandbox Code Playgroud)