0
votes

Extensions rapides avec des variables calculées avec bouclage possible?

Je veux «joliment imprimer» un tableau d'Ints sous forme hexadécimale dans Swift. J'ai ce qui suit fonctionne comme une extension de Array. Mais je ne pouvais faire fonctionner qu'une méthode arr.toHex() , et pas seulement arr.toHex comme je le voulais. Je me demande si c'est possible du tout.

Deuxièmement, en réalité, je voudrais faire arr as Hex et définir Hex d'une manière ou d'une autre. Mais aucune idée de comment.

Troisièmement, dans mon exemple de travail, je devais effectuer un cast sur Int pour que cela fonctionne. Mais parfois, ce sera un Array(Uint8) et ce casting ne fonctionne pas. Dois-je avoir utilisé une option?

J'utilise la dernière version de Swift.

extension Array where Element == Int {
    var asHex: String { "0x" + self.map { String(format: "%02X", $0) }.joined(separator: " ")
    }
}
extension Array where Element == UInt8 {
    var asHex: String { "0x" + self.map { String(format: "%02X", $0) }.joined(separator: " ")
    }
}
print( [Int(12), Int(255)].asHex )       //0x0C FF
print( [UInt8(12), UInt8(255)].asHex )   //0x0C FF

Mise à jour:

En combinant les réponses, je suis devenu très proche, mais je ne peux pas le faire fonctionner pour [Int] et [UInt8] en une seule ligne comme je l'avais prévu. Je suis arrivé à cela pour répondre aux deux types (disons Element in [Int, UInt8] :

let arr = [255, 255, 128, 64, 16]

extension Array {
    func asHex() -> String {
        var res = "0x"
        for el in self {
            res.append(String(format:"%02X", el as! Int) + " ")
        }
        return res
    }
}

print(arr.asHex())
// output: 0xFF FF 80 40 10

// would wonder whether the looping function could make into a calculated variable like this:
print(arr.asHex)
// should generate same output

// and ultimately:
print(arr as Hex)
// I have no idea how to do this

Je comprends maintenant que Int et UInt8 sont des BinaryInteger et que le $0 au format de la chaîne est un CVarArg . Pour cette raison, je ne pouvais pas utiliser l' extension Array where Element: BinaryInteger depuis le $0 plaignait. Il doit y avoir un moyen cependant. Si proche (et j'ai beaucoup appris)


3 commentaires

Pourquoi auriez-vous besoin as Hex si vous aviez une propriété calculée asHex ?


Ou ciblez-vous d'une manière ou d'une autre une fonctionnalité de conversion de type, comme l'a fait C ++? Notez qu'actuellement, cela n'est pas possible dans Swift.


as Hex était en effet une mauvaise idée. Était en train d'explorer. Pas besoin de ça.


3 Réponses :


1
votes

Pour convertir votre fonction en propriété calculée, utilisez ceci:

extension Array where Element == Int {
    var asHex: String {
        return self.map { String(format: "%02X", $0) }.joined(separator: " ")
    }
}

Ne poursuivez pas la route arr as Hex , le lancer n'est pas le bon outil pour ce problème.


0 commentaires

1
votes

`print (arr.asHex) 'ne fonctionnera pas car vous lui dites d'imprimer la méthode elle-même, pas d'exécuter la méthode et d'imprimer la sortie.

Si vous souhaitez perdre la signature de la méthode, faites-le en tant que propriété calculée:

extension Array where Element == Int{
   var asHex: String {
      var res = "0x"
      for el in self {
         res.append(String(format:"%02X", el as! Int) + " ")
      }
      return res
   }

}

let arr = [123,456,23]
print(arr.asHex)
// "0x7B 1C8 17"

vaut également la peine de contraindre l'extension comme ci-dessus afin qu'elle ne fonctionne que pour un tableau de Int


2 commentaires

Vous devriez également vous débarrasser des as! Int lorsque vous contraignez l'extension avec une clause where. Cela évitera un plantage lorsque vous essayez de forcer le transtypage d'un élément non entier en Int. Je voulais le supprimer lorsque j'ai collé votre code, il vaut donc mieux le laisser maintenant. Ou vous pouvez utiliser l'approche cartographique ci-dessous.


je l'ai. Voir mon résultat mis à jour avec la clause where. Merci



1
votes

Ne vous inquiétez pas trop as Hex , cela ne vous apportera pas trop de résultats satisfaisants dans Swift. À propos des deux autres Int8 , vous pouvez simplement étendre tous les types de Sequence basés sur Int8 ou UInt8 avec une fonctionnalité asHex :

func hexReduce(_ acc: String, _ el: CVarArg) -> String {
    acc + String(format: "%02X ", el)
}

extension Sequence where Self.Element == Int8 {
    var asHex: String { reduce("0x", hexReduce) }
}

extension Sequence where Self.Element == UInt8 {
    var asHex: String { reduce("0x", hexReduce) }
}

let arr1: [Int8] = [1, 2, 3]
let arr2: [UInt8] = [1, 2, 3]

print(arr1.asHex) // 0x01 02 03 
print(arr2.asHex) // 0x01 02 03 


0 commentaires