gpt4 book ai didi

swift - 为什么 type(of :) return Metatype, 而不是 T.Type?

转载 作者:行者123 更新时间:2023-12-04 04:28:45 25 4
gpt4 key购买 nike

我注意到 type(of:) 有这个意想不到的签名:

func type<T, Metatype>(of value: T) -> Metatype
而我本来期望:
func type<T>(of value: T) -> T.Type
实际签名以某种方式采用 2 个独立且无界的类型参数,将其中一个用作参数类型,另一个用作返回类型。这似乎表明我可以做一些像这样愚蠢的事情:
let foo: String = type(of: 1) // T is Int, Metatype is String
但是当我真正尝试时,

Cannot convert value of type 'Int.Type' to specified type 'String'


所以我没有指定 Metatype毕竟,即使它是一个泛型类型参数。我很好奇编译器是怎么做到的,所以我去了 source code。并检查。我认为阻止我做那件傻事的原因是 @_semantics注解:
@_transparent
@_semantics("typechecker.type(of:)")
public func type<T, Metatype>(of value: T) -> Metatype {
我还看到一些评论解释说这里写的实现实际上并没有被调用,这是由类型检查器本身直接处理的。但这并不能回答我的问题 - 为什么type(of:)返回一个完全不相关的类型参数 Metatype ,而不是 T.Type ?
我的猜测是有一些边缘情况 type(of:)将返回一个完全不相关的类型到 T ,但我不知道那是什么。

最佳答案

tl;博士: type(of:) 的行为取决于 T是存在的或具体的,类型系统在语法上不能有效地反射(reflect)实际的返回类型,所以直接在类型检查系统中处理。 Metatype在代码中明确不与 T 相同这样有效的行为就可以被特化。 MetatypeT不一定相关。
type(of:)特殊之处在于它的行为因传递给它的类型而异。具体来说,它对存在类型具有特殊的行为,因为它能够通过存在框来获取传入值的底层类型。例如:

func myType<T>(of value: T) -> T.Type {
return T.self
}

protocol Foo {}
struct X: Foo {}

let x = X()
print(type(of: x), "vs.", myType(of: x)) // => X vs. X

let f: Foo = X()
print(type(of: f), "vs.", myType(of: f)) // => X vs. Foo
当给定一个存在类型,如 Foo ,返回类型为 T.Type只能返回存在本身的元类型(即 Foo.self ),而不是存在容器内部值的元类型( X.self )。所以不要返回 T.Type , type(of:)返回一个不相关的类型 Metadata它绑定(bind)到类型检查器本身中的正确类型。这是您正在寻找的边缘案例:

My guess is that there is some edge case where type(of:) will return a completely unrelated type to T, but I have no idea what that is.


如果您查看 lib/Sema/TypeChecker.h ,您可以看到几种 stdlib 函数类型的一些特殊语义声明:
/// Special-case type checking semantics for certain declarations.
enum class DeclTypeCheckingSemantics {
/// A normal declaration.
Normal,

/// The type(of:) declaration, which performs a "dynamic type" operation,
/// with different behavior for existential and non-existential arguments.
TypeOf,

/// The withoutActuallyEscaping(_:do:) declaration, which makes a nonescaping
/// closure temporarily escapable.
WithoutActuallyEscaping,

/// The _openExistential(_:do:) declaration, which extracts the value inside
/// an existential and passes it as a value of its own dynamic type.
OpenExistential,
};
这里的关键是 TypeOf , 对于带有 @_semantics("typechecker.type(of:)") 的函数确实返回你注意到的属性。 (您可以在 TypeChecker::getDeclTypeCheckingSemantics 中查看如何检查该属性)
如果你去寻找 TypeOf 的用法,类型检查有两个关键位置:
  • getTypeOfReferenceWithSpecialTypeCheckingSemantics 它在类型检查器约束系统中注入(inject)类型约束。 type(of:)在这里作为重载处理,因为 Metadata实际上并没有绑定(bind);此处的约束求解器应用了一个有效的类型检查约束,该约束约束 Metadata成为 value 的实际类型. 这里的关键是 type(of:)以这种方式编写,使其成为重载,并在此处处理。
  • ExprRewriter::finishApply 它在 AST 中执行实际表达式重写,以将返回类型替换为值
  • 的有效实际类型

    从(1):
    // Proceed with a "DynamicType" operation. This produces an existential
    // metatype from existentials, or a concrete metatype from non-
    // existentials (as seen from the current abstraction level), which can't
    // be expressed in the type system currently.
    回溯一些历史——这是在提交 1889fde2284916e2c368c9c7cc87906adae9155b 中实现的.乔的提交信息很有启发性:

    Resolve type(of:) by overload resolution rather than parse hackery.

    type(of:) has behavior whose type isn't directly representable in Swift's type system, since it produces both concrete and existential metatypes. In Swift 3 we put in a parser hack to turn type(of: <expr>) into a DynamicTypeExpr, but this effectively made type(of:) a reserved name. It's a bit more principled to put Swift.type(of:) on the same level as other declarations, even with its special-case type system behavior, and we can do this by special-casing the type system we produce during overload resolution if Swift.type(of:) shows up in an overload set. This also lays groundwork for handling other declarations we want to ostensibly behave like normal declarations but with otherwise inexpressible types, viz. withoutActuallyEscaping from SE-0110.


    从那以后,我们可以从 WithoutActuallyEscaping 中看到和 OpenExistential , 其他特殊功能已被重写以利用这一点。

    关于swift - 为什么 type(of :) return Metatype, 而不是 T.Type?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67051520/

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