将通用启动参数限制为类通用类型

发布于 2025-02-12 18:28:52 字数 943 浏览 1 评论 0原文

我正在尝试为协议实现类型的擦除包装器。我的协议具有约束至caseiterable的相关类型,并且使用该类型的方法。

给定以下定义:

protocol Foo {
    associatedtype A: CaseIterable
    
    func doSomething(input: A)
}

final class AnyFoo<A: CaseIterable>: Foo {
    private let _doSomething: (A) -> Void

    init<Other: Foo>(wrappedFoo: Other) where Other.A == A {
        // "Cannot assign value of type '(Other.A) -> ()' to type '(A) -> Void'"
        _doSomething = wrappedFoo.doSomething(input:)
    }
  
    func doSomething(input: A) {
        _doSomething(input)
    }
}

我得到了错误无法分配类型的值'(other.a) - &gt; ()'tote'(a) - &gt;在类的初始化器中void'。似乎编译器将Aether.a作为不同类型解释,我不知道为什么,因为初始化器已限制了ether.a /code>和a是相同的。如果我将caseiterable替换为hashable,则没有问题。

有人可以解释为什么会发生这种情况吗?

I'm trying to implement a type erasing wrapper for a protocol. I have a protocol with an associatedtype constrainted to CaseIterable and a method using that type.

Given the following definitions:

protocol Foo {
    associatedtype A: CaseIterable
    
    func doSomething(input: A)
}

final class AnyFoo<A: CaseIterable>: Foo {
    private let _doSomething: (A) -> Void

    init<Other: Foo>(wrappedFoo: Other) where Other.A == A {
        // "Cannot assign value of type '(Other.A) -> ()' to type '(A) -> Void'"
        _doSomething = wrappedFoo.doSomething(input:)
    }
  
    func doSomething(input: A) {
        _doSomething(input)
    }
}

I'm getting the error Cannot assign value of type '(Other.A) -> ()' to type '(A) -> Void' in the initializer of the class. It seems that the compiler interprets A and Other.A as different types, and I can't figure out why, because the initializer has constrained Other.A and A to be the same. If I replace CaseIterable with Hashable, there's no problem.

Can somebody explain why this is happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泡沫很甜 2025-02-19 18:28:52

当然你不能。 _dosomething class yyfoo 是block> block的类型,它是匿名函数。因此,您可以为其分配wrappedfoo.dosomething(input:)。当您调用_dosomething(Input)时,它实际上调用wrappedfoo.dosothing(输入:输入)

从另一种方式上,您可以定义一个block喜欢:

let completion: (bool) -> void = { finished in
}

但是您不能像:

let completion: (true) -> void = { finished in
}

Of course you can't. The _doSomething in class AnyFoo is type of Block which is an Anonymous function. So you can assign wrappedFoo.doSomething(input:) to it. When you call _doSomething(input), it actually call wrappedFoo.doSomething(input: input).

In another way, you can define a Block like:

let completion: (bool) -> void = { finished in
}

but you can't define it like:

let completion: (true) -> void = { finished in
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文