[英]Invoking Right Function Implementation Based on Struct Generic Type
A struct
with a generic type can be extended with a where
clause to add new functionality when the generic type conforms to a certain protocol.具有泛型类型的struct
可以使用where
子句进行扩展,以where
泛型类型符合特定协议时添加新功能。 What am trying to accomplish is slightly different.我试图完成的事情略有不同。 I have a struct
with a generic type, and a function that I want to change its implementation if the generic type conforms to Codable
.我有一个具有泛型类型的struct
和一个函数,如果泛型类型符合Codable
,我想更改其实现。 Unfortunately, the overriden function in the extension never gets triggered, if I call the function from within the struct itself.不幸的是,如果我从结构本身内部调用函数,则扩展中的覆盖函数永远不会被触发。 But if I called it from outside, the right implementation is triggered.但是如果我从外部调用它,就会触发正确的实现。
struct GenericStruct<T> {
private var _value: T
var value: T {
get {
printText()
return _value
}
set {
_value = newValue
}
}
init(value: T) {
self._value = value
}
func printText() {
print("General Print Function")
}
}
extension GenericStruct where T: Codable {
func printText() {
print("Codable Function")
}
}
let test = GenericStruct(value: 1)
print(test.value) // print General Print Function
test.printText() // print Codable Function
Is there a way to invoke printText()
function based on T
type from within the struct?有没有办法从结构内调用基于T
类型的printText()
函数?
EDIT:编辑:
Am trying to invoke the right implementation from inside a propertyWrapper
struct我正在尝试从propertyWrapper
结构内部调用正确的实现
@propertyWrapper struct Caching<Value> {
var key: String
var defaultValue: Value
var cachingType = CachingType.userDefaults
enum CachingType {
case userDefaults
case custom
}
var wrappedValue: Value {
get {
switch cachingType {
case .userDefaults:
return UserDefaults.standard.value(forKey: key) as? Value ?? defaultValue
case .custom:
return retrieveValueFromCachingLayer()
}
}
set {
switch cachingType {
case .userDefaults:
UserDefaults.standard.set(newValue, forKey: key)
case .custom:
store(value: newValue)
}
}
}
func store(value: Value) {
assertionFailure("This value type is not supported by the property wrapper")
}
func retrieveValueFromCachingLayer() -> Value {
assertionFailure("This value type is not supported by the property wrapper")
return defaultValue
}
}
extension Caching where Value: Codable {
func retrieveValueFromCachingLayer() -> Value {
print("retrieve value from a custom caching layer")
return defaultValue
}
func store(value: Value) {
print("store value in a custom caching layer")
}
}
Not without redefinition.并非没有重新定义。 The cleanest way, I think, is to separate implementations in extensions, but you can also leave what you have already and just add the specialized value
.我认为,最简洁的方法是将扩展中的实现分开,但您也可以保留已有的内容,只添加专门的value
。
struct GenericStruct<T> {
private var _value: T
init(value: T) {
_value = value
}
}
extension GenericStruct {
var value: T {
get {
printText()
return _value
}
set {
_value = newValue
}
}
func printText() {
print("General Print Function")
}
}
extension GenericStruct where T: Codable {
var value: T {
get {
printText()
return _value
}
set {
_value = newValue
}
}
func printText() {
print("Codable Function")
}
}
Edit after learning that you're trying to work with property wrappers:在了解到您正在尝试使用属性包装器后进行编辑:
@propertyWrapper struct UserDefault<Value> {
var key: String
var defaultValue: Value
var wrappedValue: Value {
get {
UserDefaults.standard.value(forKey: key) as? Value ?? defaultValue
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
@propertyWrapper struct Caching<Value: Codable> {
var defaultValue: Value
var wrappedValue: Value {
get {
print("retrieve value from a custom caching layer")
return defaultValue
}
set {
print("store value in a custom caching layer")
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.