Je souhaite utiliser un dispatch IO channel pour lire certaines données d'un descripteur de fichier. Après avoir créé le canal, l'étape suivante consiste à appeler read
, dont la déclaration est la suivante:Incompatibilité de type dans l'incrustation Swift GCD
func read(offset: off_t,
length: Int,
queue: DispatchQueue,
ioHandler: @escaping (Bool, DispatchData?, Int32) -> Void)
La documentation pour le paramètre length
dit:
The number of bytes to read from the channel. Specify SIZE_MAX to continue reading data until an EOF is reached.
semble assez facile. Dans mon cas, je voudrais faire juste cela - lire jusqu'à EOF. Je vais passer SIZE_MAX
:
// `queue` and `handler` defined elsewhere
channel.read(offset: 0, length: SIZE_MAX, queue: queue, ioHandler: handler)
Le lecteur astucieux a deviné que le compilateur n'aime pas:
Cannot convert value of type 'UInt' to expected argument type 'Int'
SIZE_MAX
est de type UInt
, mais length
est de type Int
. Le compilateur propose de le fixer:
channel.read(offset: 0, length: Int(SIZE_MAX), queue: queue, ioHandler: handler)
Mais bien sûr, à l'exécution, cela ne fonctionne pas si bien:
fatal error: Not enough bits to represent a signed value
Naturellement, si SIZE_MAX
est la plus grande valeur par représentable UInt
, puis Int
Je ne peux pas le représenter. Après quelques recherches rapides, j'ai trouvé this exact issue on the Swift bug tracker. Comme il ne semble pas encore être traité - et je ne suis pas sûr de ma capacité à y répondre moi-même avec une demande d'extraction - comment puis-je contourner ce problème? Ou est-ce que je manque un moyen de faire ce que je veux? Le document de justification Swift Stdlib covers the explicit decision to import size_t
as Int
rather than UInt
. Il se résume à "moins de conversions de type, et qui a besoin de spécifier des nombres au-dessus de 2^63 de toute façon (désolé, plates-formes 32 bits)." Assez juste, mais cela ne couvre pas les problèmes comme le mien, où l'utilisation de SIZE_MAX
fait partie d'une API.
Est-ce que le fait de passer 'longueur: Int (bitPattern: SIZE_MAX)' fonctionne? –
Il pourrait! Il au moins compile et ne plante pas. Honnêtement, je n'ai pas encore trouvé un moyen raisonnable de tester cela.Je ne peux pas créer un flux de données d'une longueur de 2^64 octets, et je n'ai pas une idée précise de la façon dont le 'Int' est transformé en un' size_t' sur l'interface Swift vers C. – ravron