Swift学习49:Any

张建 lol

前言

在Swift中,Objective-C中的 id 类型现在映射成了Swift中的 Any 类型,它可以代表任何类型的值,无论是类、枚举、结构体还是任何其他Swift类型。这种变化使得Swift中的Objective-C API更加灵活,因为Swift定义的值类型可以传递给Objective-C API并作为Swift中的类型获取,从而无需手动“框选”类型(本人理解为转换、解包)。

集合类型

对于Swift中哈希类的集合,例如Dictionary和Set,有一个新类型 AnyHashable,可以保存任何遵守Swift中 Hashable 协议的类型的值。。Array 对应 Any

非集合类型

  • 属性列表,JSON和用户信息字典在Cocoa框架中很常见,Cocoa框架将这些表示为非类型化集合。

  • Swift可以导入 Cocoa API 接受 Any或AnyHashable 类型的集合,所以我们可以用[AnyHashable:Any]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Swift 3
struct State {
var name: String
var abbreviation: String
var population: Int

// Change the dictionary type to [AnyHashable: Any] here...
var asPropertyList: [AnyHashable: Any] {
var result: [AnyHashable: Any] = [:]
// No implicit conversions necessary, since String and Int are subtypes
// of Any and AnyHashable
result["name"] = self.name
result["abbreviation"] = self.abbreviation
result["population"] = self.population
return result
}
}
let california = State(name: "California",
abbreviation: "CA",
population: 39_000_000)
// ...and you can still use it with Cocoa API here
Notification(name: "foo", object: nil,
userInfo: california.asPropertyList)

未链接上下文的显式转换

在某些确定的情况下,Swift不能自动桥接C和Objective-C。 例如,一些C和Cocoa API使用id *指针作为“out”或“in-out”参数,并且由于Swift不能静态地确定指针的使用方式,因此它不能对内存中的值自动执行桥接转换 。 在这种情况下,指针仍将显示为UnsafePointer 。 如果您需要使用到这些不能自动桥接转换的API,您可以使用显式桥接转换,在代码中使用 as Typeas AnyObject 显式转换。

1
2
3
4
5
// ObjC
@interface Foo
- (void)updateString:(NSString **)string;
- (void)updateObject:(id *)obj;
@end
1
2
3
4
5
6
7
8
9
10
11
12
// Swift
func interactWith(foo: Foo) -> (String, Any) {
var string = "string" as NSString // explicit conversion
foo.updateString(&string) // parameter imports as UnsafeMutablePointer<NSString>
let finishedString = string as String

var object = "string" as AnyObject
foo.updateObject(&object) // parameter imports as UnsafeMutablePointer<AnyObject>
let finishedObject = object as Any

return (finishedString, finishedObject)
}

另外,Objective-C中的协议在Swift中仍然是类约束(及只有类才可以遵守协议),所以你不能让Swift中的结构体或枚举直接遵守Objective-C中的协议或者是使用轻量级的泛型类。 当您需要使用到这些协议和API时应该像这样 String as NSStringArray as NSArray 进行显式转换。

  • Post title:Swift学习49:Any
  • Post author:张建
  • Create time:2023-03-14 06:34:03
  • Post link:https://redefine.ohevan.com/2023/03/14/Swift课程/Swift学习49:Any/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.