如何定义Swift协议,使实现可以是属性或方法?

如何定义Swift协议,使实现可以是属性或方法?,swift,swift-protocols,Swift,Swift Protocols,以下是我想做的: import Foundation import UIKit protocol PlayableMediaItem { func title() -> String func albumArt() -> UIImage func audioFileURL() -> URL } struct AudioTrack : Codable, PlayableMediaItem { var title: String var

以下是我想做的:

import Foundation
import UIKit

protocol PlayableMediaItem {
    func title() -> String
    func albumArt() -> UIImage
    func audioFileURL() -> URL
}


struct AudioTrack : Codable, PlayableMediaItem {
    var title: String
    var desc:String
    var albumArtDemoName:String
    var audioDemoFilename:String

    func albumArt() -> UIImage {
        let image = UIImage(named: albumArtDemoName)
        return image!
    }

    func audioFileURL() -> URL {
        return Bundle.main.url(forResource: audioDemoFilename, withExtension: "mp3")!
    }
}
但我得到的错误是,AudioTrack不符合PlayableMediaItem协议,因为
title
属性不是一个方法,而是一个属性

我如何设置它,使
标题
相册
等可以实现为属性或方法,只要它们返回正确的类型


我的一些实现可能只是属性,而其他实现是计算的

只需在协议中将其声明为属性,并使用计算属性而不是使用方法:

import Foundation
import UIKit

protocol PlayableMediaItem {
    var title: String { get } 
    var albumArt: UIImage { get }
    var audioFileURL: URL { get }
}


struct AudioTrack : Codable, PlayableMediaItem {
    var title: String
    var desc:String
    var albumArtDemoName:String
    var audioDemoFilename:String

    var albumArt: UIImage {
        let image = UIImage(named: albumArtDemoName)
        return image!
    }

    var audioFileURL: URL {
        return Bundle.main.url(forResource: audioDemoFilename, withExtension: "mp3")!
    }
}

只需在协议中将其声明为属性,并使用计算属性而不是使用方法:

import Foundation
import UIKit

protocol PlayableMediaItem {
    var title: String { get } 
    var albumArt: UIImage { get }
    var audioFileURL: URL { get }
}


struct AudioTrack : Codable, PlayableMediaItem {
    var title: String
    var desc:String
    var albumArtDemoName:String
    var audioDemoFilename:String

    var albumArt: UIImage {
        let image = UIImage(named: albumArtDemoName)
        return image!
    }

    var audioFileURL: URL {
        return Bundle.main.url(forResource: audioDemoFilename, withExtension: "mp3")!
    }
}

更改协议以使用属性而不是函数。通过这种方式,实现结构/类可以决定将其实现为不动产或计算属性

protocol PlayableMediaItem {
    var title: String { get }
    var albumArt: UIImage { get }
    var audioFileURL: URL { get }
}

更改协议以使用属性而不是函数。通过这种方式,实现结构/类可以决定将其实现为不动产或计算属性

protocol PlayableMediaItem {
    var title: String { get }
    var albumArt: UIImage { get }
    var audioFileURL: URL { get }
}

不完全确定您需要什么,因为这取决于具体情况,但可以尝试让它们成为变量而不是funcs,然后在实现协议的类上,您可以操作它们的get/set变量

struct Square {
 var edge: Double = 0
 var area: Double {
get {
  return edge * edge
}
set {
  edge = sqrt(newValue)
}}

不完全确定您需要什么,因为这取决于具体情况,但可以尝试让它们成为变量而不是funcs,然后在实现协议的类上,您可以操作它们的get/set变量

struct Square {
 var edge: Double = 0
 var area: Double {
get {
  return edge * edge
}
set {
  edge = sqrt(newValue)
}}

为什么你需要他们成为你的方法?您可以使用计算属性来满足协议的属性要求,它的行为就像一个不接受返回结果的参数的方法。为什么需要它们作为方法?您可以使用计算属性来满足协议的属性要求,该属性的作用与不接受返回结果的参数的方法类似