Fast protocol with associated type (ambiguous for type search)

I need to create a generic function in a protocol with a default implementation in the extension. The func function should work with the element as enum: RawRepresentablewhere RawValue == Stringalways. I tried

protocol RequiresEnum: class {
    associatedtype SectionIdentifierEnum: RawRepresentable // how this add restriction to RawValue == String

    func test<T: SectionIdentifierEnum>(identifier: T) where T.RawValue == String
}

enum RequiresEnumDefault: String {
    case `default`
}

extension RequiresEnum where Self: UIViewController, SectionIdentifierEnum.RawValue == String {

    typealias SectionIdentifierEnum = RequiresEnumDefault

    func test<T: SectionIdentifierEnum>(identifier: T) where T.RawValue == String {
        print(T.rawValue)
    }

}

but i have errors

  • 'SectionIdentifierEnum' is ambiguous for type search in this context
  • 'RawValue' is not a member type of 'T'

Any solutions

+4
source share
1 answer

, - associatedtype . SectionIdentifierEnum, . SectionIdenfierEnum , , , . test(...).


Swift 3.1

, (Swift 3.1), associatedtype. , , Self UIViewController RequiresEnum, SectionIdentifierEnum RequiresEnumDefault. , RawValue String , RawValue RequiresEnumDefault - String.

:.

// Swift 3.1
// ---------
// Types that implement this protocol mustn't necessarily use a
// `SectionIdentifierEnum` type where `SectionIdentifierEnum.RawValue` 
// is constrained to equal `String`. 
protocol RequiresEnum: class {
    associatedtype SectionIdentifierEnum: RawRepresentable

    func test(identifier: SectionIdentifierEnum)
}

enum RequiresEnumDefault: String {
    case `default`
}

// This extension, however, is only available for types that use
// `RequiresEnumDefault ` as the concrete type of `SectionIdentifierEnum`
// (in which case `SectionIdentifierEnum.RawValue` is `String`).
extension RequiresEnum where Self: UIViewController, SectionIdentifierEnum == RequiresEnumDefault {

    func test(identifier: SectionIdentifierEnum) {
        print(identifier.rawValue)
    }
}

// Example usage.
class MyViewController : UIViewController, RequiresEnum {
    typealias SectionIdentifierEnum = RequiresEnumDefault
    // ...
}

let foo = MyViewController()
foo.test(identifier: RequiresEnumDefault.default) 
  // prints "default" (using extension:s default implementation)

, test(...) , SectionIdentifierEnum RequireEnumDefault ( Self UIViewController...). , , SectionIdentifierEnum String typed RawValue, :

protocol RequiresEnum: class {
    associatedtype SectionIdentifierEnum: RawRepresentable

    func test(identifier: SectionIdentifierEnum)
}

enum RequiresEnumDefault: String {
    case `default`
}

extension RequiresEnum where Self: UIViewController, SectionIdentifierEnum.RawValue == String {

    func test(identifier: SectionIdentifierEnum) {
        print(identifier.rawValue)
    }
}


// Example usage.
enum EnumWithStringRawValue: String {
    case foo
}

class MyViewController : UIViewController, RequiresEnum {
    typealias SectionIdentifierEnum = EnumWithStringRawValue
    // ...
}

let foo = MyViewController()
foo.test(identifier: EnumWithStringRawValue.foo)
    // prints "foo" (using extension:s default implementation)

, Swift 4 , associatedtype: s Swift:

:

// Swift 4
// -------
// Here, all types that implement this protocol must use a
// `SectionIdentifierEnum` type where `SectionIdentifierEnum.RawValue` 
// is equal to `String`. 
protocol RequiresEnum: class {
    associatedtype SectionIdentifierEnum: RawRepresentable 
        where SectionIdentifierEnum.RawValue == String

    func test(identifier: SectionIdentifierEnum)
}

enum RequiresEnumDefault: String {
    case `default`
}

// For the specific case where `SectionIdentifierEnum` equals
// `RequiresEnumDefault` (and where `Self` derives from `UIViewController`), 
// this default implementation is readily available.
extension RequiresEnum where Self: UIViewController, SectionIdentifierEnum == RequiresEnumDefault {

    func test(identifier: SectionIdentifierEnum) {
        print(identifier.rawValue)
    }

}

// Example usage.
class MyViewController : UIViewController, RequiresEnum {
    typealias SectionIdentifierEnum = RequiresEnumDefault
    // ...
}

let foo = MyViewController()
foo.test(identifier: RequiresEnumDefault.default) 
  // prints "default" (using extension:s default implementation)

, test(...) , SectionIdentifierEnum RequiresEnumDefault ( : , RawValue String, - associatedtype ).

protocol RequiresEnum: class {
    associatedtype SectionIdentifierEnum: RawRepresentable 
        where SectionIdentifierEnum.RawValue == String

    func test(identifier: SectionIdentifierEnum)
}

enum RequiresEnumDefault: String {
    case `default`
}

// From the constraint on the `RawValue` of `SectionIdentifierEnum`
// above, we know that `RawValue` equals `String`.
extension RequiresEnum where Self: UIViewController {

    func test(identifier: SectionIdentifierEnum) {
        print(identifier.rawValue)
    }
}

// Example usage.
enum EnumWithStringRawValue: String {
    case foo
}
class MyViewController : UIViewController, RequiresEnum {
    typealias SectionIdentifierEnum = EnumWithStringRawValue
    // ...
}

let foo = MyViewController()
foo.test(identifier: EnumWithStringRawValue.foo) 
  // prints "foo" (using extension:s default implementation)
+3

Source: https://habr.com/ru/post/1682426/


All Articles