如何声明一个符合协议的具体返回类型的函数?

7

编辑: 在添加some关键字之前,该问题是在swift之前编写的,因此已过时。

在Objective-C中,我可以声明一个带有返回类型的方法:

-(UIView<MyProtocol> *)someMethod;

在这个示例中,该方法返回一个符合协议MyProtocolUIView
我想在Swift中做类似的事情:
protocol MyProtocol {
  var someProperty : Int {get set}
}

protocol MyDelegate {
  func someMethod() -> UIView : MyProtocol // the view should conform to the protocol - I don't care what kind of view it is - I don't want to define a specific type of view
}

一般来说,委托应该返回一个带有变量“someProperty”的UIView
不想定义一个具体的UIView类。我希望用户能够返回任何类型UIView(只要符合协议)。
我写的语法是无效的 - 我应该如何编写它?

很可能你可以在许多编程语言中完成这样的事情。这与Objective-C没有特定的关系。已删除标签。 - Amin Negm-Awad
5个回答

0

您可以直接使用协议作为类型:

protocol MyDelegate {
    func someMethod() -> MyProtocol
}

并像这样使用它:

protocol MyProtocol {
    var someProperty : Int {get set}
}

class CustomView: UIView, MyProtocol {
    var someProperty = 2
}

protocol MyDelegate {
    func someMethod() -> MyProtocol
}

struct Delegate: MyDelegate {
    func someMethod() -> MyProtocol {
        return CustomView()
    }
}

let delegate = Delegate()
let view = delegate.someMethod()
let property = view.someProperty // property = 2

1
第一个不确定地回答了问题。我会尝试第二个。 - Avba
1
虽然缺少 UIView 约束,但它可以保证协议一致性。 - József Vesza
无法工作;出现错误:一行上的连续声明必须用“;”分隔。 - Avba
我遇到了一些Xcode问题,所以它没有抛出错误,但我发现我的做法是错误的。我更新了答案,提供了唯一可行的示例(我不确定你怎么能做到)。 - József Vesza

0
protocol MyProtocol {
  var someProperty : Int {get set}
}

protocol MyDelegate {
  func someMethod<T: UIView & MyProtocol>() -> T // the view should conform to the protocol - I don't care what kind of view it is - I don't want to define a specific type of view
}

class MyDelegateTestView : UIView, MyProtocol {
    var someProperty: Int = 10
}

class MyDelegateTestClass : MyDelegate {
    func someMethod<T>() -> T where T : UIView, T : MyProtocol {
        return MyDelegateTestView() as! T
    }
}

0

在Swift中不可能实现这一点。并非Obj-C中的所有功能都必须在Swift中实现。当创建类型要求时,您只能使用protocol<..., ...>语法组合协议,但无法组合类和协议。

从技术上讲,这对于您的架构应该是有好处的。您可能可以找到解决方法,但我建议不要这样做。避免将类与协议组合在一起是有原因的,因为接口更难处理。大多数面向对象编程语言都没有这种语法。许多常用语言甚至没有组合协议的语法。


当然可以。几乎所有的编程语言都可以从一个超类继承并实现尽可能多的接口(协议)。 - Avba
这是所有 Objective-C 及 UIKit/Foundation 框架中广泛使用的模式。 - Avba
@AvnerBarr 我不是在谈论继承,我是在谈论在传递参数、从方法返回等时指定类型要求。我知道在 Obj-C 中这是可能的(虽然不经常使用但是可能)。但在包括 Swift 在内的大多数其他语言中都是不可能的。 - Sulthan
Uikit 定义了返回类型为 Uiview 的方法,实现了接口。这对于将视图添加到层次结构中非常有用,而不会强制特定类型,同时在对象上定义方法和变量。 - Avba
@AvnerBarr,你能否提供其中一个链接吗?我现在想不起来有这样的方法了。无论如何,我知道它可能很有用,但有更简洁的方式来实现相同的功能。Swift就是没有这个功能,就像大多数其他编程语言一样。 - Sulthan

0

这个问题是在 Swift UI 问世之前提出的。

"some" 关键字通过允许从函数返回不透明类型来解决了这个问题。

protocol MyDelegate {
  func someMethod() -> some MyProtocol 
}

-2

以下是一种方法。

func myMethod(string: String) -> MyClass:MyProtocol? {

}

你可以将 MyClass 声明为 MyProtocol,而不需要使用可选类型。


1
出现相同的错误:一行上连续的声明必须用“;”分隔。 - Avba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接