suzuki sport precio boosterjet swift

sport - suzuki swift boosterjet



¿Cómo crear Diccionario que pueda contener cualquier cosa en Key? o todo el tipo posible que sea capaz de contener (8)

Quiero crear un Dictionary que no limite el tipo de clave (como NSDictionary )

Así que lo intenté

var dict = Dictionary<Any, Int>()

y

var dict = Dictionary<AnyObject, Int>()

resultante

error: type ''Any'' does not conform to protocol ''Hashable'' var dict = Dictionary<Any, Int>() ^ <REPL>:5:12: error: cannot convert the expression''s type ''<<error type>>'' to type ''$T1'' var dict = Dictionary<Any, Int>() ^~~~~~~~~~~~~~~~~~~~~~

OK, Hashable

var dict = Dictionary<Hashable, Int>()

pero

error: type ''Hashable'' does not conform to protocol ''Equatable'' var dict = Dictionary<Hashable, Int>() ^ Swift.Equatable:2:8: note: ''=='' requirement refers to ''Self'' type func ==(lhs: Self, rhs: Self) -> Bool ^ Swift.Hashable:1:10: note: type ''Hashable'' does not conform to inherited protocol ''Equatable.Protocol'' protocol Hashable : Equatable ^ <REPL>:5:12: error: cannot convert the expression''s type ''<<error type>>'' to type ''$T1'' var dict = Dictionary<Hashable, Int>() ^~~~~~~~~~~~~~~~~~~~~~~~~~~

¿ Hashable heredado de Equatable pero no se ajusta a Equatable ? No entiendo...

De todos modos, sigue intentando

typealias KeyType = protocol<Hashable, Equatable> // KeyType is both Hashable and Equatable var dict = Dictionary<KeyType, Int>() // now you happy?

sin suerte

error: type ''KeyType'' does not conform to protocol ''Equatable'' var dict = Dictionary<KeyType, Int>() ^ Swift.Equatable:2:8: note: ''=='' requirement refers to ''Self'' type func ==(lhs: Self, rhs: Self) -> Bool ^ Swift.Hashable:1:10: note: type ''KeyType'' does not conform to inherited protocol ''Equatable.Protocol'' protocol Hashable : Equatable ^ <REPL>:6:12: error: cannot convert the expression''s type ''<<error type>>'' to type ''$T1'' var dict = Dictionary<KeyType, Int>() ^~~~~~~~~~~~~~~~~~~~~~~~~~

Estoy tan perdido ahora, ¿cómo puedo hacer que el compilador esté contento con mi código?

Quiero usar el diccionario como

var dict = Dictionary<Any, Int>() dict[1] = 2 dict["key"] = 3 dict[SomeEnum.SomeValue] = 4

Sé que puedo usar Dictionary<NSObject, Int> , pero en realidad no es lo que quiero.


Swift 3 actualización

Ahora puede usar AnyHashable que es un valor hashable borrado por tipo, creado exactamente para escenarios como este:

var dict = Dictionary<AnyHashable, Int>()


Creo que, a partir de Swift 1.2, puede usar una estructura ObjectIdentifier para esto. Implementa Hashable (y por lo tanto Equatable) así como Comparable. Puede usarlo para envolver cualquier instancia de clase. Supongo que la implementación usa la dirección subyacente del objeto envuelto para hashValue, así como dentro del operador ==.


El diccionario es struct Dictionary<Key : Hashable, Value>... Lo que significa que Value puede ser cualquier cosa que desee, y Key podría ser del tipo que desee, pero Key debe cumplir con el protocolo Hashable .

No puede crear Dictionary<Any, Int>() o Dictionary<AnyObject, Int>() , porque Any y AnyObject no pueden garantizar que dicha clave se ajuste a Hashable

No puede crear Dictionary<Hashable, Int>() , porque Hashable no es un tipo, solo es un protocolo que describe el tipo necesario.

¿Hashable heredado de Equatable pero no se ajusta a Equatable? No entiendo...

Pero te equivocas en terminología. Error original es

type ''Hashable'' does not conform to inherited protocol ''Equatable.Protocol'' Esto significa que Xcode asume ''Hashable'' como algún tipo, pero no existe tal tipo. Y Xcode lo trata como un tipo de tipo vacío, que obviamente no concuerda con ningún protocolo (en este caso no cumple con el protocolo heredado Equatable )

Algo similar ocurre con KeyType .

Una declaración de alias de tipo introduce un alias con nombre de un tipo existente en su programa.

Ves existing type . protocol<Hashable, Equatable> no es un tipo, es un protocolo, por lo que Xcode vuelve a decirle que el type ''KeyType'' does not conform to protocol ''Equatable''

Puede usar Dictionary<NSObject, Int> just, porque NSObject cumple Hashable protocolo Hashable .

Swift es un lenguaje fuerte de tipeo y no puedes hacer cosas como creating Dictionary that can hold anything in Key . En realidad, el diccionario ya admite que cualquiera puede contener cualquier cosa en Key, que se ajusta a Hashable . Pero dado que debe especificar una clase particular, no puede hacer esto para las clases Swift nativas, porque no existe tal clase maestra en Swift como en Objective-C, que puede adaptarse según el aire (con la ayuda de extensiones) a Hashable

Por supuesto, puedes usar una envoltura como la sugerida por chrisco . Pero realmente no puedo imaginar por qué lo necesitas. Es genial que tengas un tipeo fuerte en Swift para que no tengas que preocuparte por la conversión de tipos como lo hiciste en Objective-C


Esto no responde a la pregunta del OP, pero está relacionado de alguna manera y, con suerte, puede ser útil para algunas situaciones. Supongamos que lo que realmente quieres hacer es esto:

public var classTypeToClassNumber = [Any.Type : Int]()

Pero Swift te está diciendo que "Tipo" Any.Type "no se ajusta al protocolo Hashable".

La mayoría de las respuestas anteriores se refieren al uso de instancias de objetos como una clave de diccionario, sin utilizar el tipo de objeto. (Lo cual es justo, eso es lo que el OP estaba preguntando). Fue la respuesta de Howard Lovatt la que me llevó a una solución utilizable.

public class ClassNumberVsClassType { public var classTypeToClassNumber = [String : Int]() public init() { classTypeToClassNumber[String(describing: ClassWithStringKey.self)] = 367622 classTypeToClassNumber[String(describing: ClassBasedOnKeyedItemList3.self)] = 367629 classTypeToClassNumber[String(describing: ClassBasedOnKeyedItemList2.self)] = 367626 classTypeToClassNumber[String(describing: ClassWithGuidKey.self)] = 367623 classTypeToClassNumber[String(describing: SimpleStruct.self)] = 367619 classTypeToClassNumber[String(describing: TestData.self)] = 367627 classTypeToClassNumber[String(describing: ETestEnum.self)] = 367617 classTypeToClassNumber[String(describing: ClassBasedOnKeyedItemList0.self)] = 367624 classTypeToClassNumber[String(describing: ClassBasedOnKeyedItemList1.self)] = 367625 classTypeToClassNumber[String(describing: SimpleClass.self)] = 367620 classTypeToClassNumber[String(describing: DerivedClass.self)] = 367621 } public func findClassNumber(_ theType : Any.Type) -> Int { var s = String(describing: theType) if s.hasSuffix(".Type") { s = s.substring(to: s.index(s.endIndex, offsetBy: -5)) // Remove ".Type" } let classNumber = _classTypeToClassNumber[s] return classNumber != nil ? classNumber! : -1 } }

EDITAR:

Si las clases implicadas están definidas en módulos diferentes, y pueden tener nombres de clases conflictivos si descuida el nombre del módulo, entonces sustituya "Cadena (reflejando:" por "Cadena (describiendo:"), tanto al compilar el diccionario como al realizar la búsqueda .


Esto no responde exactamente la pregunta, pero me ha ayudado.

La respuesta general sería implementar Hashable para todos sus tipos, sin embargo, eso puede ser difícil para los Protocolos porque Hashable extiende Self y Equatable usa Self que impone limitaciones severas sobre para qué se puede usar un protocolo.

En su lugar, implemente Imprimible y luego haga lo siguiente:

var dict = [String: Int] dict[key.description] = 3

La implementación de la descripción tiene que ser algo así como:

var description : String { return "<TypeName>[/(<Field1>), /(<Field2>), ...]" }

No es una respuesta perfecta, pero la mejor que tengo hasta ahora :(


Me tomé la libertad de realizar publicaciones cruzadas / enlaces a esta pregunta en una publicación separada en los foros de Apple Dev y esta pregunta se devforums.apple.com/message/1045616 .

Editar

Esta respuesta del enlace de arriba funciona en 6.1 y mayor:

struct AnyKey: Hashable { private let underlying: Any private let hashValueFunc: () -> Int private let equalityFunc: (Any) -> Bool init<T: Hashable>(_ key: T) { underlying = key // Capture the key''s hashability and equatability using closures. // The Key shares the hash of the underlying value. hashValueFunc = { key.hashValue } // The Key is equal to a Key of the same underlying type, // whose underlying value is "==" to ours. equalityFunc = { if let other = $0 as? T { return key == other } return false } } var hashValue: Int { return hashValueFunc() } } func ==(x: AnyKey, y: AnyKey) -> Bool { return x.equalityFunc(y.underlying) }



Hashable es solo un protocolo, por lo que no puede especificarlo directamente como un tipo para el valor Key . Lo que realmente necesita es una forma de expresar "cualquier tipo T, tal que T implemente Hashable . Esto se maneja mediante restricciones de tipo en Swift:

func makeDict<T: Hashable>(arr: T[]) { let x = Dictionary<T, Int>() }

Este código compila

AFAIK, solo puedes usar restricciones de tipo en las clases y funciones genéricas.