簡體   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