假设我有以下协议:
protocol Identifiable {
var id: Int {get}
var name: String {get}
}
Run Code Online (Sandbox Code Playgroud)
而且我有以下结构:
struct A: Identifiable {
var id: Int
var name: String
}
struct B: Identifiable {
var id: Int
var name: String
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我必须"符合"结构A和结构B中的可识别协议.但想象一下,如果我有N个结构需要符合这个协议......我不想'复制/粘贴' '一致性(var id:Int,var name:String)
所以我创建了一个协议扩展:
extension Identifiable {
var id: Int {
return 0
}
var name: String {
return "default"
}
}
Run Code Online (Sandbox Code Playgroud)
现在有了这个扩展,我可以创建一个符合Identifiable协议的结构,而不必实现这两个属性:
struct C: Identifiable {
}
Run Code Online (Sandbox Code Playgroud)
现在问题是我无法为id属性或name属性设置值:
var c: C = C()
c.id = 12 // Cannot assign to …Run Code Online (Sandbox Code Playgroud) 我有一个协议,我为其分配了一些默认值:
protocol HigherProtocol {
var level: Int { get }
func doSomething()
}
extension HigherProtocol {
var level: Int { 10 }
func doSomething() {
print("Higher level is \(level)")
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有另一个协议,它符合更高级别的协议,但具有不同的默认值和函数实现:
protocol LowerProtocol: HigherProtocol {}
extension LowerProtocol {
var level: Int { 1 }
func doSomething() {
print("Lower level is \(level)")
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建一个符合 HigherProtocol 的类,然后创建一个符合较低级别协议的子类:
class HigherClass: HigherProtocol {}
class LowerClass: HigherClass, LowerProtocol {}
Run Code Online (Sandbox Code Playgroud)
然而,当我实例化这个较低的类时,它显示了一些奇怪的行为:
let lowerClass = LowerClass()
lowerClass.level // is 1
lowerClass.doSomething() // Prints "Lower level …Run Code Online (Sandbox Code Playgroud) 我用这段代码看到了这个问题:
protocol Flashable {}
extension Flashable where Self: UIView
{
func flash() {
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn, animations: {
self.alpha = 1.0 //Object fades in
}) { (animationComplete) in
if animationComplete == true {
UIView.animate(withDuration: 0.3, delay: 2.0, options: .curveEaseOut, animations: {
self.alpha = 0.0 //Object fades out
}, completion: nil)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
而且我想知道为什么我们不只是直接扩展UIView?或者在类似的情况下延伸UIViewController为什么用a扭转它where Self:
我不明白为什么我会收到此错误。SomeController是一个类,而不是一个结构,并且它不是不可变的。有解决办法吗?
class SomeController: APIFetchable {
let baseUrl = "https://jsonplaceholder.typicode.com"
let defaultSession = URLSession(configuration: .default)
var dataTask: URLSessionTask?
func fetchDataFromAPI(atPath path: String, _ callback: ()-> Void){
fetchDataAtPath(path) { data, error in /*Error on this line -> "Cannot use mutating member on immutable value: 'self' is immutable"*/
}
}
}
protocol APIFetchable {
var baseUrl: String {get}
var defaultSession: URLSession {get}
var dataTask: URLSessionTask? {get set}
mutating func fetchDataAtPath(_ path: String, _ callback: @escaping (Data?, Error?)-> Void)
}
extension APIFetchable …Run Code Online (Sandbox Code Playgroud) 我有一个描述需要测试的海水参数的协议:
protocol Parameter {
var name: String { get }
var unit: Unit { get }
var value: Double { get }
}
Run Code Online (Sandbox Code Playgroud)
我有一个结构Calcium符合,符合Parameter:
struct Calcium: Parameter {
var name: String = "Calcium"
var unit: Unit = UnitDispersion.partsPerMillion
var value: Double
}
Run Code Online (Sandbox Code Playgroud)
由于name和unit参数Calcium都有默认值,为什么我需要在init方法中提供它们?我不应该只需要提供一个值value吗?
我正在尝试理解面向协议的编程,并且非常感谢这里的一些指导.