我一直在努力寻找一个解决方案,使用泛型和相关类型在另一个相关类型中解决上述问题
我想要一个ObjectRequestType
,其中包含ObjectResponseType
类型的关联类型。
protocol ObjectRequestType {
associatedtype Response: ObjectResponseType
}
另一方面, ObjectResponseType
是具有关联类型Element
protocol ObjectResponseType {
associatedtype Element
}
我想要实现的是我想根据不同类型的元素扩展ObjectRequestType
的功能,这里为了示例我们有两种不同类型的Element
。
protocol ElementType {}
protocol OtherElementType {}
到目前为止,我将通过以下扩展程序实现此目的
extension ObjectRequestType where Response.Element: ElementType {
static func request() {
print("ElementType")
}
}
extension ObjectRequestType where Response.Element: OtherElementType {
static func request() {
print("OtherElementType")
}
}
额外的步骤是处理将此请求传递给我需要使用泛型的类
class DemoClass<Request: ObjectRequestType> {
static func execute() {
Request.request()
}
}
由于动态DemoClass
无法定义Response
Request
有哪种OtherElementType
,它会找到它的两个实现,并且它将无法抛出编译错误
错误:对成员'request()'
的模糊引用
通过添加额外的where子句来修改类仍然不会这样做,因为我会错过class DemoClass<Request: ObjectRequestType> where Request.Response.Element: ElementType {
static func execute() {
Request.request()
}
}
的其余实现
foreach ($Comp in (Get-Content 'C:\full_path_to_the_source_file\hosts.txt')) {
foreach ($UserFolder in (Get-ChildItem "\\$Comp\c$\Users" -Directory)) {
$DocumentsFolder = Join-Path ($UserFolder.FullName) 'Documents'
$DesktopFolder = Join-Path ($UserFolder.FullName) 'Desktop'
$DocumentsSize = (Get-ChildItem $DocumentsFolder -Recurse | Measure-Object -property length -sum -ErrorAction SilentlyContinue)
$DesktopSize = (Get-ChildItem $DesktopFolder -Recurse | Measure-Object -property length -sum -ErrorAction SilentlyContinue)
$DocumentOutput = "$Comp $UserFolder Documents {0:N1}" -f ($DocumentsSize.sum / 1GB) + "GB"
$DesktopOutput = "$Comp $UserFolder Desktop {0:N1}" -f ($DesktopSize.sum / 1GB) + "GB"
$DocumentOutput | Out-File \\Some_Server\Share\Results\Results.txt -Append
$DesktopOutput | Out-File \\Some_Server\Share\Results\Results.txt -Append
}
}
我一直在尝试使用它的解决方法,但我仍然无法实现这种情况。如果有人有任何想法或其他方法,我们将非常欢迎。
答案 0 :(得分:2)
执行此操作的常用方法是将request
方法添加到ObjectResponseType
协议中,以便您可以保证它存在于任何符合标准的类型上。然后,您创建一个协议扩展,为您已知的如何处理的类型提供默认实现,您已经完成了。如果您需要使用现有元素类型之一覆盖某个请求的请求,则可以执行此操作。如果您需要支持其他元素类型,您可以在请求中执行此操作,也可以添加其他协议扩展名。
protocol ObjectResponseType {
associatedtype Element
}
protocol ObjectRequestType {
associatedtype Response: ObjectResponseType
static func request()
}
protocol ElementType {}
extension ObjectRequestType where Response.Element: ElementType {
static func request() {
print("ElementType")
}
}
protocol OtherElementType {}
extension ObjectRequestType where Response.Element: OtherElementType {
static func request() {
print("OtherElementType")
}
}
class DemoClass<Request: ObjectRequestType> {
static func execute() {
Request.request()
}
}
class Foo: ElementType {}
class FooResponse: ObjectResponseType {
typealias Element = Foo
}
class FooRequest: ObjectRequestType {
typealias Response = FooResponse
}
class Bar: OtherElementType {}
class BarResponse: ObjectResponseType {
typealias Element = Bar
}
class BarRequest: ObjectRequestType {
typealias Response = BarResponse
// Override the default implementation
static func request() {
print("Bar")
}
}
class Baz {}
class BazResponse: ObjectResponseType {
typealias Element = Baz
}
class BazRequest: ObjectRequestType {
typealias Response = BazResponse
static func request() {
print("Baz")
}
}
DemoClass<FooRequest>.execute() // ElementType
DemoClass<BarRequest>.execute() // Bar
DemoClass<BazRequest>.execute() // Baz