Реализация правильной реализации функции на основе типа Struct Generi c - PullRequest
0 голосов
/ 25 марта 2020

A struct с типом generi c может быть расширен с помощью предложения where для добавления новых функций, когда тип generi c соответствует определенному протоколу. То, что я пытаюсь сделать sh, немного отличается. У меня есть struct с типом generi c и функция, которую я хочу изменить в своей реализации, если тип generi c соответствует Codable. К сожалению, переопределенная функция в расширении никогда не срабатывает, если я вызываю функцию из самой структуры. Но если я вызываю его извне, запускается правильная реализация.

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

Есть ли способ вызвать функцию printText() на основе типа T из структуры?

EDIT:

Я пытаюсь вызвать правильную реализацию из propertyWrapper struct

@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")
    }
}

1 Ответ

0 голосов
/ 25 марта 2020

Не без переопределения. Я думаю, что самым чистым способом является разделение реализаций в расширениях, но вы также можете оставить то, что у вас уже есть, и просто добавить специализированное 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 после изучения того, что вы пытаетесь работа с обёртками свойств:

@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")
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...