Old*_*ier 18 arrays casting swift
说我有一个数组AnyObject
.
let grabBag: [AnyObject] = [ "Tom", 4, "Dick", NSObject(), "Harry" ]
Run Code Online (Sandbox Code Playgroud)
我想将它转换为一个数组Strings
,只提取那些实际上的元素Strings
.我希望这可行:
let strings = grabBag.filter{ $0 is String } as! [String] // 1
Run Code Online (Sandbox Code Playgroud)
但它给出了错误'Bool' is not convertible to 'String'
.但这有效:
let definitelyStrings = grabBag.filter{ $0 is String } // 2
let strings = definitelyStrings as! [String] //
Run Code Online (Sandbox Code Playgroud)
为什么不2
工作1
?而且是有一个更简单的(除2
提取和铸造的元素)的方式[AnyObject]
,以什么[T]
?
aya*_*aio 30
最好使用flatMap
一个漂亮的单线程:
let strings = grabBag.flatMap { $0 as? String }
Run Code Online (Sandbox Code Playgroud)
现在strings
是类型[String]
.
更新:在Swift 4.2中你应该使用compactMap
而不是flatMap
:
let strings = grabBag.compactMap { $0 as? String }
Run Code Online (Sandbox Code Playgroud)
这flatMap
是为了什么:
let strings = grabBag.flatMap{ $0 as? String }
Run Code Online (Sandbox Code Playgroud)
这需要一个返回可选的闭包; 如果optional是非nil,则将其添加到结果中.
(请注意,这 Rob Mayoff指出,如果Optionals是序列类型,它们可能应该是,这将是一个明智的名称.)flatMap
与其他语言的含义不符,甚至与flatMap
Swift 中的其他含义不匹配.更好的名称可能是mapOptional
或mapSome
.但它仍然是直观的,即使不一致.它"映射对于选项,然后扁平化所有的nils."
我想说测试 1 失败显然是编译器错误。事实上它在 REPL 中崩溃了:
Welcome to Apple Swift version 2.0 (700.1.100.2 700.1.74). Type :help for assistance.
1> import Foundation
2> let grabBag: [AnyObject] = [ "Tom", 4, "Dick", NSObject(), "Harry" ]
grabBag: [AnyObject] = 5 values {
[0] = "Tom"
[1] = Int64(4)
[2] = "Dick"
[3] = {
isa = NSObject
}
[4] = "Harry"
}
3> let strings = grabBag.filter { $0 is String } as! String
strings: String = {
_core = {
_baseAddress =
_countAndFlags =
_owner = <extracting data from value failed>
}
}
Execution interrupted. Enter Swift code to recover and continue.
Enter LLDB commands to investigate (type :help for assistance.)
4> :bt
* thread #1: tid = 0x501bac, 0x00000001005c41f4 $__lldb_expr12`main + 420 at repl.swift:3, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
* frame #0: 0x00000001005c41f4 $__lldb_expr12`main + 420 at repl.swift:3
frame #1: 0x0000000100001420 repl_swift`_mh_execute_header + 5152
frame #2: 0x00007fff8dd725c9 libdyld.dylib`start + 1
frame #3: 0x00007fff8dd725c9 libdyld.dylib`start + 1
Run Code Online (Sandbox Code Playgroud)
不管怎样,正如 Rob Napier 也回答的那样,grabBag.flatMap { $0 as? String }
更短,也许更简单。
归档时间: |
|
查看次数: |
7314 次 |
最近记录: |