加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

将Swift泛型类转换为具有typealias的协议

发布时间:2020-12-14 04:46:11 所属栏目:百科 来源:网络整理
导读:我疯了还是不应该这个快速的代码编译? protocol Protocol { typealias Thing}class ClassX: Protocol { typealias Thing = X}func testX:Protocol where X.Thing == Int () - X { return ClassInt() // error: cannot convert return expression of type 'C
我疯了还是不应该这个快速的代码编译?

protocol Protocol {
  typealias Thing
}

class Class<X>: Protocol {
  typealias Thing = X
}

func test<X:Protocol where X.Thing == Int> () -> X {
  return Class<Int>()  // error: cannot convert return expression of type 'Class<Int>' to return type 'X'
}

即使泛型类型和aliastype匹配,我似乎无法将对象强制转换为其协议.

编辑:

我通过从现有代码中提取逻辑来提出上述代码,以简化问题.这样做我犯了一些错误.这是一个更新的(并且希望不那么令人困惑)代码示例:

protocol Protocol {
    typealias Thing
}
class Class<X>: Protocol {
    typealias Thing = X
}
func test<Y: Protocol where Y.Thing == Int> () -> Y {
    return Class<Y.Thing>()
}

我希望编译器允许test()编译,结果类型为Protocol< Int>.

解决方法

在今天的Swift中你的回归类型是不可能的.具有关联类型(PAT)的协议是抽象的.应用where子句不会改变它.考虑以下代码:

let x: <WHAT-GOES-HERE?> = test()

x会是什么类型的?没有什么可以写在那里编译. x.Type会返回什么?你想要的是Protocol,其中Protocol.Thing == Int,但这不是Swift中的一个类型.这是一种类型约束.这是今天可以使用PAT的唯一方法.这就是为什么你不能拥有CollectionType< Int>类型的属性,以及为什么你不能编写test()函数.

该解决方案是一种类型橡皮擦,可将您的协议转换为具体的结构.例如:

protocol Protocol {
    typealias Thing
    func dosomething() -> Thing?
}
class Class<X>: Protocol {
    typealias Thing = X
    func dosomething() -> Thing? {
        return nil
    }
}

struct AnyProtocol<Thing> {
    var _dosomething: () -> Thing?
    func dosomething() -> Thing? {
        return _dosomething()
    }
}

func test() -> AnyProtocol<Int> {
    return AnyProtocol(_dosomething: Class<Int>().dosomething)
}

Swift的某些未来版本可能会为您自动生成这些类型的橡皮擦,但我不知道任何具体的Swift-evolution建议,所以我们今天必须手工编写它们.

有关构建和使用类型擦除器的更多信息,请参阅A Little Respect for AnySequence.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读