schinj
schinj

Reputation: 804

Value of protocol type '*' cannot conform to '*'; only struct/enum/class types can conform to protocols

I am facing the above error while trying this:

    protocol Style {}
    
    struct StyleA: Style {}
    struct StyleA: Style {}
    struct StyleA: Style {}

    struct Preset: Identifiable {
        let id: UUID = UUID()
        let title: String
        let style: Style
    }

    extension View {
        public func applyStyle<S>(_ style: S) where S : Style {
            // USe the style here
        }
    }
    

    // Initializg the data
    static let mockedData: [Preset] = [
        .init(title: "Title A", style: StyleA()),
        .init(title: "Title A", style: StyleB()),
        .init(title: "Title A", style: StyleC()),
    ]
    
// This line gives the error
    myView.applyStyle(mockedData.first!.style)


How can I fix it? Shouldn't it resolve the concrete type?

Thanks for your help.

Upvotes: 1

Views: 2562

Answers (3)

David Pasztor
David Pasztor

Reputation: 54716

You're running into the problem of protocols not conforming to themselves. Your problem can be easily solved by making applyStyle non-generic, since Style can be used as a concrete type.

extension View {
    public func applyStyle(_ style: Style) {
        // USe the style here
    }
}

Upvotes: 1

Kstin
Kstin

Reputation: 679

try

public protocol Style {}

struct StyleA: Style {}
struct StyleB: Style {}
struct StyleC: Style {}

struct Preset: Identifiable {
    let id: UUID = UUID()
    let title: String
    let style: Style
}

extension View {
    public func applyStyle(_ style: Style){
        // USe the style here
    }
}


// Initializg the data
let mockedData: [Preset] = [
    .init(title: "Title A", style: StyleA()),
    .init(title: "Title A", style: StyleB()),
    .init(title: "Title A", style: StyleC()),
]

myView.applyStyle(mockedData.first!.style)

Upvotes: 0

E. Vladov
E. Vladov

Reputation: 81

Since the Preset member style is Style, not any concrete type, you don't need the applyStyle to be generic, you can simply say:

  public func applyStyle(_ style: Style) 

Upvotes: 0

Related Questions