protocol Persisting {
func persist()
}
extension Persisting {
func persist() { print("persisting") }
}
protocol Service {
func get()
func persistIfAble() // If I remove this, "Not able to persist" gets printed twice
}
extension Service {
func get() {
persistIfAble()
}
}
extension Service {
func persistIfAble() {
print("Not able to persist")
}
}
extension Service where Self: Persisting {
func persistIfAble() {
persist()
}
}
struct OnlyService: Service {}
struct Both: Service, Persisting {}
let both = Both()
both.get()
let onlyService = OnlyService()
onlyService.get()
print("Can now directly call `persistIfAble` which is not wanted")
onlyService.persistIfAble() // DONT WANT THIS TO BE POSSIBLE
如果我可以从协议声明中删除func persistIfAble()
,那么这个解决方案会很优雅。因为我不希望它暴露出来。 然而,真正有趣的是,如果我删除它,然后行为发生变化,那么extension Service where Self: Persisting
内的实现永远不会被调用。
protocol Persisting {
func persist()
}
extension Persisting {
func persist() { print("persisting") }
}
protocol Service {
func get()
}
extension Service {
func get() {
// Ugly solution, I do not want to cast, `Service` should not have to know about `Persisting`
if let persisting = self as? Persisting {
persisting.persist()
} else {
print("not able to persist")
}
}
}
extension Service where Self: Persisting {
func persistIfAble() {
persist()
}
}
struct OnlyService: Service {}
struct Both: Service, Persisting {}
let both = Both()
both.get()
let onlyService = OnlyService()
onlyService.get()
丑陋的解决方案中的代码当然是我实际场景的极其简化的版本,我真的不想执行强制转换,因为它使代码更难以阅读。即使我将if let
更改为guard let
。
protocol Persisting {
func persist()
}
extension Persisting {
func persist() { print("persisting") }
}
protocol Service {
func get()
func persistIfAble(allowed: Bool)
}
extension Service {
func get() {
persistIfAble(allowed: true)
}
}
extension Service {
func persistIfAble(allowed: Bool = false) {
guard allowed else { print("KILL APP"); return }
print("Not able to persist")
}
}
extension Service where Self: Persisting {
func persistIfAble(allowed: Bool = false) {
guard allowed else { print("BREAKING RULES"); return }
persist()
}
}
struct OnlyService: Service {}
struct Both: Service, Persisting {}
let both = Both()
both.get()
let onlyService = OnlyService()
onlyService.get()
print("Can now directly call `persistIfAble` which is not wanted")
// DONT WANT THIS TO BE POSSIBLE
onlyService.persistIfAble() // prints: "KILL APP"
美丽的解决方案在哪里?
答案 0 :(得分:1)
我想知道你真正想要的是使用实际对象的组合,而不仅仅是接口(以及一些默认实现)。考虑一下:Persisting
和Service
正如您所定义的那样,确实需要在具体的类或结构中实现,以便它们可以包含有关它们访问数据的位置的上下文。所以我想你可以跳过协议扩展,把真正的“胆量”留给那些协议的具体实现,然后你的Both
就像这样实现:
struct Both: Persisting, Service {
let persisting: Persisting
let service: Service
// a default init lets you pass in concrete implementations of both of those things
func persist() {
persisting.persist()
}
func get() {
service.get()
persist()
}
这显然不会给你自动排序的“混入”效果,它看起来像你想要实现的,但OTOH很清楚要理解。
答案 1 :(得分:0)
如何删除一个间接级别(即' persistIfAble')?
View.OnClickListener