Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

992
Visualizações
Swift enum conformance to identifiable: Type doesn't conform to Identifiable protocol

I have an enum with associated values, which I want to use as an item in RxDataSources. I tried conforming it to identifiable by conforming it to Hashable like below

enum DriverHubWidget: Hashable, Identifiable {
    static func == (lhs: DriverHubWidget, rhs: DriverHubWidget) -> Bool {
        return lhs.hashValue == rhs.hashValue
    }
    
    var id: Int { hashValue }
    
    case greetings(DriverHubGreetingsViewModel)
    case scorecard(DriverHubScorecardSummary?, Error?)
    case optOut
    
    func hash(into hasher: inout Hasher) {
        switch self {
        case .greetings( _):
            return hasher.combine(1)
        case .scorecard( _, _):
            return hasher.combine(2)
        case .optOut:
            return hasher.combine(3)
        }
    }
}

I implemented the hasher function by simply assigning each case an Int value. Then to conform to identifiable, I added an id property that returns the hashValue. This compiles just fine.

Now when I try to use this to declare a type alias for the section model, like below

typealias WidgetSection = AnimatableSectionModel<String, DriverHubWidget>

It does compile and throws the error, Type 'DriverHubWidget' does not conform to protocol 'IdentifiableType'

I can't understand why it doesn't work, it compiles fine when the enumis comformed to Hashable and Identifiable, but when used the conformance somehow is invalid Is it because the associated values for the enums re not Hashable?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

(This isn’t a full answer, but it’s too long for a comment. Consider it an addendum to what Sweeper already said)

For objects to be Identifiable, they need to have a stable (I.e. doesn’t change over time) notion of identity that distinguishes them from other relates objects. Exactly what notion of identity makes sense for your purposes is up to you. As the documentation mentions:

Identifiable leaves the duration and scope of the identity unspecified.

  • Identities can have any of the following characteristics: Guaranteed always unique, like UUIDs.
  • Persistently unique per environment, like database record keys.
  • Unique for the lifetime of a process, like global incrementing integers.
  • Unique for the lifetime of an object, like object identifiers.
  • Unique within the current collection, like collection indices. It’s up to both the conformer and the receiver of the protocol to document the nature of the identity.
  1. You probably don’t want to ignore the associated values from your notion of identity. Otherwise, your code might tried two objects as identical, even if their associated values differ.

    In practice, that means that DriverHubGreetingsViewModel, DriverHubScorecardSummary will also need to conform to Identifiable. Your Error? associated value, you’ll probably want to make into (Error & Identifiable)?*

  2. You can’t delicate your implementation of id to hashValue, because hash values are (by design) unpredictable. It’s entirely possible that all three of your cases end up with the same id (this would happen if the hashed was seeded in such a way that the hashes of 1, 2 and 3 all collid)

Another note: having an optional model, followed by an optional error is a code smell in Swift. This is a holdover from Objective C, whose type system lacked a leightweight way to express a value of one type or another (an “or” or “sum” type). Swift supports enums with associated values (you’re already using one!) which can even be generic. There’s one already built into the Standard library for you: Result<Success, Failure>

So rather than case scorecard(DriverHubScorecardSummary?, Error?), I would recommend:

case scorecard(Result<DriverHubScorecardSummary, Error & Identifiable>)
over 4 years ago · Santiago Trujillo Relatório

0

You have confused Identifiable, a Swift built-in protocol, with IdentifiableType, a protocol in the RxDataSource library.

You can just conform to IdentifiableType.

enum DriverHubWidget: Hashable, IdentifiableType {
    
    var identity: Int {
        hashValue
    }

    ...
}

The way you conform to Hashable seems weird to me though. You are considering two values of the enum equal as long as they are the same case, and disregarding their associated values. That is, .greeting(x) == .greeting(y) would be true. This seems rather counterintuitive. If this is really what you want for identity, you might want to just implement identity this way:

var identity: Int {
    switch self {
    case .greetings( _):
        return 1
    case .scorecard( _, _):
        return 2
    case .optOut:
        return 3
    }
}

and conform to Hashable by actually taking the associated values into account, or not conform to Hashable at all.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda