为什么我无法将Protocol.Type传递给通用T.Type参数? [英] Why can't I pass a Protocol.Type to a generic T.Type parameter?

查看:85
本文介绍了为什么我无法将Protocol.Type传递给通用T.Type参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在和Swinject合作,一个问题在困扰着我。几乎整整一天,我都被困在这一块。我怀疑这是由于Swift是一种静态类型的语言,但我不完全确定。



我在这个游乐场里总结了我的问题

  protocol Protocol {} 
$ b $ class Class:Protocol {}

let test:Protocol.Type = Class .self

func printType(confromingClassType:Protocol.Type){$ b $ print(confromingClassType)
}

func printType< Service>(serviceType:Service .Type){
print(serviceType)
}

print(Class.self)//Class
printType(serviceType:Class.self)// class
print(test)//Class
printType(confromingClassType:test)//Class

printType(serviceType:test)//note:预期会有一个类型为'(serviceType:Service.Type)'

的参数列表test.self或type(of:test),但它们都不起作用。

所以我想我不能用一个通用参数调用一个函数作为变量?

解决方案

P.Type P.Protocol



有两种协议元类型。对于某些协议 P 和符合类型 C





您遇到的问题是,对于给定的通用占位符 T ,当 T 是一些协议 P T.Type P.Type - 它是 P.Protocol



所以如果我们回到你的例子:

  protocol P {} 
class C :P {}

func printType< T>(serviceType:T.Type){
print(serviceType)
}

let test:P .Type = C.self

//不能调用'printType '的类型为'(serviceType:P.Type)'的参数列表'
printType(serviceType:test)

我们无法将 test 作为参数传递给 printType(serviceType:)。为什么?因为 test P.Type ;并且没有替换 T ,这使得 serviceType:参数取< P.Type 。



如果我们用 P 代替 T ,该参数需要一个 P.Protocol

  printType(serviceType:P.self)//很好,P.self是P.Protocol类型,而不是P.Type 

如果我们用 类型替换 T ,比如 C ,参数需要一个 C.Type

  printType serviceType:C.self)// C.self是C.Type类型






使用协议扩展破解



好的,所以我们知道如果我们可以用对于 T ,我们可以将 C.Type 传递给函数。我们可以在动态类型中替换 P.Type 包装吗?不幸的是,这需要一种称为开放存在< a>,目前不能直接提供给用户。



然而,当访问协议类型的成员时,Swift 确实隐含地打开了存在实例或元类型(即,它挖出运行时类型并使其以通用占位符的形式可访问)。我们可以在协议扩展中利用这个事实:

 协议P {} 
class C:P {}

func printType< T>(serviceType:T.Type){
print(T.self = \(T.self))
print(serviceType = \(serviceType))
}

extension P {
static func callPrintType / *< Self:P> * /(/ * _ self:Self.Type * /){
printType(serviceType:self)
}
}

let test:P.Type = C.self
test.callPrintType()
// T.self = C
// serviceType = C

这里有很多东西在做,所以让我们稍微解开它:



查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆