繁体   English   中英

如何在函数的返回类型中引用遵循协议的类?

[英]How to reference a class that follows a protocol in return type of function?

我有一个名为“社会服务”的协议,声明如下:

protocol SocialService: class {
    class func testFunc()
}

遵循该协议的类可能如下所示:

class Twitter: SocialService {
    class func testFunc() {

    }
}

我想有一个返回遵循此协议的类的方法,因此调用它的方式将如下所示:

let socialService = socialServiceForServiceType(serviceType: String)

我不确定该函数的返回值类型需要输入什么。 例如,这:

func socialServiceForServiceType(serviceType: String) -> SocialService.Type

在这里没有给出错误,但是尝试如上所述调用它会产生错误:

访问协议类型值'SocialService.Type'的成员未实现

编辑:我不想这种类型的实例,我想要那种类型的类。 因此,我需要一个Twitter类,以便可以从其上的SocialService协议调用类方法。

就像错误所述,此功能未实现。 然而...

我不想要那种类型的实例,我想要那种类型的类。 因此,我需要一个Twitter类,以便可以从其上的SocialService协议调用类方法。

我不确定避免这种情况对您有什么帮助。 请记住,类不需要具有成员变量,没有它们,它们本质上只是函数指针的集合–这似乎是您想要的。

如果您实现一个没有属性且符合协议的Twitter类,则该协议上的调用方法将动态分派到该实例的实现:

protocol SocialService: class {
    func testFunc()
}

class Twitter: SocialService {
    func testFunc() {
        println("Testing Twitter!")
    }
}

func socialServiceForServiceType(serviceType: String) -> SocialService {
    return Twitter()
}

let service = socialServiceForServiceType("blah")

// prints "Testing Twitter!"
service.testFunc()

如果您担心要在Twitter类中放入成员变量,但又不想为某些功能增加开销,那么这可能表明您希望将此功能分解为两个不同的类。 另外,如果您想要一个单例实例(例如,处理连接性),则可以使用其他模式来处理。

简单使用

func socialServiceForServiceType(serviceType: String) -> SocialService

协议可以是函数的返回类型。

完全同意Airspeed Velocity,但我想谈一谈他的观点:

我不确定避免这种情况对您有什么帮助。 请记住,类不需要具有成员变量,没有它们,它们本质上只是函数指针的集合–这似乎是您想要的。

我认为您正在尝试执行以下操作:

func socialServiceForServiceType(serviceType: String) -> SocialService.Type
...
let cls = socialServiceForServiceType("twitter")
let conn = cls.connect(user)

或类似的东西。 您不需要类即可实现。 您可以只返回函数。

typealias Connect = User -> Connection
func connectorForServiceType(serviceType: String) -> Connect {
     switch serviceType {
         case "twitter": return Twitter.Connect
         ...
     }
}

let connect = connectorForServiceType("twitter")
let conn = connect(user)

如果您有要打包在一起的一整套功能,则只需使用结构即可。

struct ServiceHandlers {
    let connect : User -> Connection
    let ping : () -> Bool
    let name: () -> String
}

func standardPinger(host: String) -> () -> Bool {
    return { host in 
        // perform an ICMP ping and return Bool 
    }
}

func handlersForServiceType(serviceType: String) -> ServiceHandlers {
     switch serviceType {
         case "twitter":
             return ServiceHandlers(connect: Twitter.connect,
                                    ping: standardPinger("www.twitter.com"), 
                                    name: { "Twitter" })
         ...
     }
}

let service = handlersForServiceType("twitter")
let conn = service.connect(user)

在某些方面,这与类方法是重复的,但是(a)未实现类方法所需的功能,并且(b)更加灵活。 您可以返回所需的任何功能集合; 他们不必全部都是类方法。 具有默认行为(使用继承在Swift中很难做到)更容易。 扩展起来更容易,因为您不必扩展所有类(请参阅我对standardPinger使用,这是我组成的一些函数,可以返回另一个函数;它不一定是一个类方法)。

摆脱类/继承性思维而只是传递函数可能是Swift的一大好处。 有时结构比协议更好。

使用Factory模式来实现相同的目的。

class SocialFactory : NSObject
{
  class func socialServiceForServiceType(serviceType: String) -> SocialService?
  {
    switch serviceType
    {
      case "Twitter":
         return Twitter();
      case "Facebook":
         return Facebook()
      default:
         return nil;
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM