当前位置: 首页 > 面试题库 >

不支持将某些协议用作符合其他协议的具体类型

何乐
2023-03-14
问题内容

我正在尝试将泛型与协议混合在一起,而xD却变得非常困难

我在Android / Java项目中实现了某些架构,并且尝试将其重写以使其适合swift / iOS项目。但是我发现了这个限制。

ProtocolA

protocol ProtocolA {

}

ProtocolB

protocol ProtocolB : ProtocolA {

}

ImplementProtocolA

class ImplementProtocolA <P : ProtocolA> {

    let currentProtocol : P

    init(currentProtocol : P) {
        self.currentProtocol = currentProtocol
    }

}

ImplementProtocolB

class ImplementProtocolB : ImplementProtocolA<ProtocolB> {

}

因此,当我尝试将ProtocolB设置为实现
ProtocolA的具体类型时,出现此错误:

不支持将“ ProtocolB”用作符合协议“ ProtocolA”的具体类型

1这种“限制”有什么理由吗?

2有什么解决方法可以实现此目标吗?

3是否会在某个时候提供支持?

  • 更新-

我认为,同一问题的另一个变体是:

查看协议

protocol View {

}

protocol GetUserView : View {
    func showProgress()
    func hideProgress()
    func showError(message:String)
    func showUser(userDemo:UserDemo)
}

Presenter protocols

protocol Presenter {
    typealias V : View
}

class UserDemoPresenter : Presenter {
    typealias V = GetUserView
}

Error:

UserDemoPresenter.swift Possibly intended match ‘V’ (aka ‘GetUserView’) does
not conform to ‘View’

What is that?? It conforms!

Even if I use View instead of GetUserView, it does not compile.

class UserDemoPresenter : Presenter {
    typealias V = View
}

UserDemoPresenter.swift Possibly intended match ‘V’ (aka ‘View’) does not
conform to ‘View’

xxDD I don’t get it, really.

  • 更新-

使用罗布·纳皮尔(Rob Napier)提出的解决方案,问题并没有得到解决,而
只是被延迟了。

尝试定义对UserDemoPresenter的引用时,我需要指定
通用类型,因此会出现相同的错误:

private var presenter : UserDemoPresenter<GetUserView>

Using ‘GetUserView’ as a concrete type conforming to protocol ‘GetUserView’
is not supported


问题答案:

该限制的根本原因是Swift没有一流的元
类型。最简单的例子是,这不起作用:

func isEmpty(xs: Array) -> Bool {
    return xs.count == 0
}

从理论上讲,此代码可以工作,如果可以,
我可以创建很多其他类型的代码(例如Functor和Monad,
今天在Swift中实际上还无法表达它们)。但是你不能。您需要帮助Swift将其固定为
具体类型。通常,我们使用泛型来做到这一点:

func isEmpty<T>(xs: [T]) -> Bool {
    return xs.count == 0
}

注意,T这里完全多余。我没有理由要
表达它。它从未使用过。但是Swift需要它,因此它可以将摘要
Array变成具体的[T]。您的情况也是如此。

这是一个具体类型(嗯,它是一个抽象类型,在
实例化并P填充时会变成具体类型):

class ImplementProtocolA<P : ProtocolA>

This is a fully abstract type that Swift doesn’t have any rule to turn into a
concrete type:

class ImplementProtocolB : ImplementProtocolA<ProtocolB>

You need to make it concrete. This will compile:

class ImplementProtocolB<T: ProtocolB> : ImplementProtocolA<T> {}

And also:

class UserDemoPresenter<T: GetUserView> : Presenter {
    typealias V = T
}

只是因为您以后可能会遇到此问题:如果您要创建这些结构或final类,您的生活就会轻松得多。混合协议,泛型和类多态性充满了非常尖锐的边缘。有时您很幸运,而且它无法编译。有时它会发出您
意想不到的事情。

您可能对一点尊重
任何序列感兴趣,该序列详细介绍了一些相关问题。

private var presenter : UserDemoPresenter<GetUserView>

This is still an abstract type. You mean:

final class Something<T: GetUserView> {
    private var presenter: UserDemoPresenter<T>
}

如果这样会产生问题,则需要创建一个框。看到协议不符合自身?讨论如何进行类型擦除,以便
保留抽象类型。但是您需要处理具体类型。您最终不能专注于协议。在大多数情况下,您最终必须专注于具体的事情。



 类似资料:
  • 问题内容: 我正在使用Swift 2,并使用WeakContainer作为存储一组弱对象的方法,就像 然后在我的ViewController中,声明 但这是错误的 不支持将MyDelegate用作符合协议AnyObject的具体类型 我看到错误是成员已声明为,因此应该是对象。但是我也声明为。如何解决这个问题? 问题答案: 我有相同的想法,用泛型创建弱容器。 结果,我为创建了包装器,并为您的编译器错

  • WorkerMan在接口上支持各种协议,只要符合ConnectionInterface接口即可(参见定制通讯协议章节)。 为了方便开发者,WorkerMan提供了HTTP协议、WebSocket协议以及非常简单的Text文本协议、可用于二进制传输的frame协议。开发者可以直接使用这些协议,不必再二次开发。如果这些协议都不满足需要,开发者可以参照定制协议章节实现自己的协议。 开发者也可以直接基于t

  • 问题内容: 编译错误如下: 类型“ AnyObject”不符合协议“ SequenceType” 这种压力是什么? 谁能帮我很多忙! 问题答案: 苹果在Swift编程语言中指出: for-in循环针对范围,序列,集合或进度中的每个项目执行一组语句。 目前,它仅符合protocol ,因此您无法在其上使用for循环。如果要这样做,则必须执行类似以下操作:

  • 问题内容: Beta 3一切正常,现在出现一个奇怪的错误,而且我不知道如何解决它。尝试了所有类似问题的解决方案。 这是我的代码: 两条标记线都给了我相同的错误: 类型“ String.Index”不符合协议“ IntegerLiteralConvertible” 有人能帮我吗?还是Beta 4有漏洞?谢谢! 问题答案: 在Beta 4中,Swift的String.Index处理再次发生了变化- 现

  • 本文向大家介绍Dubbo支持哪些协议,每种协议的应用场景,优缺点?相关面试题,主要包含被问及Dubbo支持哪些协议,每种协议的应用场景,优缺点?时的应答技巧和注意事项,需要的朋友参考一下 dubbo: 单一长连接和NIO异步通讯,适合大并发小数据量的服务调用,以及消费者远大于提供者。传输协议TCP,异步,Hessian序列化; rmi: 采用JDK标准的rmi协议实现,传输参数和返回参数对象需要实

  • 下面的代码是TCP客户端的套接字编程示例。 但当我运行该操作时,connect()作为协议不支持的地址族返回。