gpt4 book ai didi

swift - Swift 5 中的 THE.self 是什么?

转载 作者:行者123 更新时间:2023-12-05 08:48:01 26 4
gpt4 key购买 nike

我目前正在浏览 Landmarks 应用程序教程,我在将 JSON 加载到结构中的部分。他们给出了以下代码。

引用:https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation

import Foundation


func load<T: Decodable>(_ filename: String) -> T {

let data: Data


guard let file = Bundle.main.url(forResource: filename, withExtension: nil)

else {

fatalError("Couldn't find \(filename) in main bundle.")

}


do {

data = try Data(contentsOf: file)

} catch {

fatalError("Couldn't load \(filename) from main bundle:\n\(error)")

}


do {

let decoder = JSONDecoder()

return try decoder.decode(T.self, from: data)

} catch {

fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")

}

}

我特别不明白 T.self引用也不 <T: Decodable>在函数的开头。有人能分解这个功能吗?谢谢。

最佳答案

我看到这个问题在评论中得到了回答,但我觉得对于那些试图理解泛型的 Swift 新手来说,这个问题值得一个实际的回答。

为了回答这个问题,让我们看看T是什么,它定义在函数的签名中

func load<T: Decodable>(_ filename: String) -> T

这表示通用函数 load(_:String) -> T 返回一些符合 Decodable 的类型 T,所以 T 是引用返回值类型的通用方式,其中该类型将根据调用站点的上下文确定,具体而言,由接收返回值的任何类型决定。

被询问的行是

return try decoder.decode(T.self, from: data)

这里 T.self 是一种引用类型 T 本身的方式。如果您查看 decode 的函数签名,您会发现它看起来像这样:

func decode<T: Decodable>(_ type: T.Type, from data: Data) throws -> T

请注意,参数类型 T.Type type。这意味着参数 type 将保存类型 T 而不是类型 T 的值。这是 Swift 区分指定变量是类型的值还是它的值是类型本身的方法。一开始这可能有点令人困惑,但一旦您了解了泛型,它就会变得有意义。

因为 Swift 是一种强类型语言,类型是在编译时定义的,decode 需要知道它试图解码的对象的类型。在 JavaScript 或 Python 等无类型语言中,这不是必需的。在那些语言中,对象基本上是字典,因此它总是可以解码字典(或数组,或一小组基本类型之一)。在 Swift 中,structclass 只是字典的语法糖。它们更像是 C 风格的 struct - 一组二进制数据,具有由类型决定的特定内存布局。为了正确解码,decode 必须知道它在解码什么,而且最常见的是,如何通过它的 init(from: Decoder) throws 方法告诉那个东西解码自己(可能已由编译器合成)。它会调用 NSImage.init(from: Decoder) 还是 String.init(from: Decoder) 等...?

如果您熟悉在 OOP 中实现运行时多态性的方式,提供类型,甚至是一般性的,提供了一种获取类型的协议(protocol)见证表的方法 - 这是协议(protocol)等同于“vtable”该类用于虚拟方法的运行时动态分派(dispatch)。所以它让它做一些类似于在 OOP 中调用虚拟方法的事情,除了它通常可以在编译时计算出来,并且它可以同时适用于值类型和引用类型。了解他的工作原理还可以深入了解不同但相关的问题,例如为什么直接在协议(protocol)中声明的所需方法与仅在协议(protocol)扩展中声明的方法(基本上在协议(protocol)中直接声明的方法在协议(protocol)中)得到不同的多态行为witness 表,因此它们可以被动态调度,而仅在扩展中的那些不在 witness 表中,因此任何特定于类型的实现都将丢失,而只能调用协议(protocol)扩展中的实现)。

以下函数使用它来打印其参数的类型(有更好的方法,但这说明了 T.TypeT.self):

func foo<T>(_ value: T)
{
let typeOfValue: T.Type = T.self
print("The value, \(value), is of type, \(typeOfValue).")
}

关于swift - Swift 5 中的 THE.self 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66631340/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com