Swift: специализированная реализация методов с расширениями протокола

Чтобы обеспечить некоторый контекст:

P означает собственность. Цель кода состоит в том, что значения разных типов должны обрабатываться отдельными методами (например, serializeInt, serializeDouble и т. д.), что-то вроде перегрузки метода, но тип аргумента исходит из параметра типа.

Код ниже действительно работает нормально. Он вызывает специализированную реализацию pr( _: Int) и печатает «int».

Но если я изменю объявление "func pr(_ t: Int)" на закомментированное "func pr(_ t: T)", то будет вызвана универсальная версия.

У кого-нибудь есть какие-либо указатели на то, где указано это поведение или почему оно работает так?

  protocol P {
     associatedtype T
     // this will be 'specialized' for concrete types
     func pr(_ t: T)

     // the operation that should call different pr implementations depending on T
     func op(_ t: T)
  }

  extension P {
     func op(_ t: T) {
        pr(t)
     }
  }

  // fallback implementation
  extension P {
     func pr(_ t: T) {
        print("generic")
     }
  }

  // pr 'specialized' on Int
  extension P where T == Int {
     //   func pr(_ t: T) {
     func pr(_ t: Int) {
        print("int")
     }
  }


  struct Prop<T>: P {
  }

  // create an Int prop and do the op
  let p = Prop<Int>()

  p.op(1)

person E. Vladov    schedule 21.08.2018    source источник
comment
Столкнулся с той же проблемой. Любое решение?   -  person Michael_mhr    schedule 15.06.2019
comment
Что ж, мое замешательство произошло из-за того, что я не понял, что общий параметр T и связанный с ним тип T — это не одно и то же. Что касается конкретной проблемы, с которой я столкнулся, я закончил определение другого протокола SettingsBacked и согласование стандартных типов с ним.   -  person E. Vladov    schedule 15.06.2019


Ответы (1)


Не наблюдайте странного поведения. Если раскомментировать эту строку — func pr(_ t: T) {

Здесь p.op(1) будет вызывать метод по умолчанию, потому что вы не предоставили реализацию для op метода where T == Int. И по умолчанию op вызывает по умолчанию pr, поэтому он печатает «общий».

person Bohdan Savych    schedule 21.08.2018
comment
Я имел в виду, что если код станет: extension P where T == Int { func pr(_ t: T) { print("int") } }, то он перестанет вызываться - person E. Vladov; 22.08.2018