[英]How can I define a Swift Protocol so that the implementation can be a property _or_ a method?
Here's what I want to do: 这是我想做的:
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")!
}
}
But I get the error that AudioTrack doesn't conform to the PlayableMediaItem protocol because the title
property isn't a method, it's a property. 但是我得到一个错误,即AudioTrack不符合PlayableMediaItem协议,因为
title
属性不是方法,而是属性。
How can I set this up so that title
, albumArt
, etc. can be implemented as either properties or methods, so long as they give me back the right type? 我怎样才能设置这让
title
, albumArt
等均可实现为属性或方法,只要他们给我回到正确的类型?
Some of my implementations of this might just be properties, while others are computed. 我对此的一些实现可能只是属性,而其他实现是经过计算的。
Just declare it as a property in the protocol, and use a computed property instead of using a method: 只需在协议中将其声明为属性,然后使用计算的属性而不是使用方法即可:
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")!
}
}
Change your protocol to use properties instead of functions. 更改您的协议以使用属性而不是函数。 That way implementing struct/class can decide to have it implemented as real property or computed one.
通过这种方式,实现struct / class可以决定将其实现为不动产还是经过计算的财产。
protocol PlayableMediaItem {
var title: String { get }
var albumArt: UIImage { get }
var audioFileURL: URL { get }
}
Not entirely sure what you need, since it depends but maybe try making them variables instead of funcs and then on classes that implement the protocol you can manipulate their get/set of the var. 并不是完全确定您需要什么,因为这取决于但可以尝试使它们成为变量而不是funcs,然后在实现该协议的类上可以操纵其var的获取/设置。
struct Square {
var edge: Double = 0
var area: Double {
get {
return edge * edge
}
set {
edge = sqrt(newValue)
}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.