Ich möchte eine dispatch IO channel verwenden, um einige Daten aus einem Dateideskriptor zu lesen. Nachdem der Kanal zu schaffen, ist der nächste Schritt read
zu nennen, deren Erklärung ist wie folgt:Typ Mismatch in Swift GCD Overlay
func read(offset: off_t,
length: Int,
queue: DispatchQueue,
ioHandler: @escaping (Bool, DispatchData?, Int32) -> Void)
Die Dokumentation für die Parameter length
sagt:
The number of bytes to read from the channel. Specify SIZE_MAX to continue reading data until an EOF is reached.
leicht genug zu sein scheint. In meinem Fall würde ich genau das tun - bis EOF lesen. Also werde ich SIZE_MAX
passieren:
// `queue` and `handler` defined elsewhere
channel.read(offset: 0, length: SIZE_MAX, queue: queue, ioHandler: handler)
Der aufmerksame Leser hat gedacht, dass der Compiler dies nicht mag:
Cannot convert value of type 'UInt' to expected argument type 'Int'
SIZE_MAX
ist vom Typ UInt
, aber length
ist vom Typ Int
. Der Compiler bietet es zu beheben:
channel.read(offset: 0, length: Int(SIZE_MAX), queue: queue, ioHandler: handler)
Aber natürlich zur Laufzeit, wird dies nicht so gut funktionieren:
fatal error: Not enough bits to represent a signed value
Natürlich, wenn SIZE_MAX
der größte Wert darstellbaren UInt
ist, dann Int
kann es nicht darstellen. Nach kurzer Suche fand ich this exact issue on the Swift bug tracker. Da es anscheinend noch nicht angesprochen ist - und ich mich nicht sicher bin, ob ich es mit einer Pull-Anfrage selbst angehen kann - wie kann ich dieses Problem umgehen? Oder fehlt mir eine Möglichkeit, das zu tun, was ich will?
Die Swift Stdlib rationale dokumentiert covers the explicit decision to import size_t
as Int
rather than UInt
. Es läuft auf "weniger Typkonvertierungen hinaus, und wer Zahlen über 2^63 sowieso spezifizieren muss (Entschuldigung, 32-Bit-Plattformen)." Fair genug, aber das gilt nicht für Probleme wie meine, wo die Verwendung von SIZE_MAX
Teil einer API ist.
Funktioniert die Weitergabe von 'length: Int (bitPattern: SIZE_MAX)? –
Es könnte! Es kompiliert zumindest und stürzt nicht ab. Ehrlich gesagt, habe ich noch keinen vernünftigen Weg gefunden, das zu testen.Ich kann nicht genau einen Datenstrom erstellen, der 2^64 Bytes lang ist, und ich habe kein festes Handle darüber, wie genau das "Int" über die Swift to C Schnittstelle in ein "size_t" umgewandelt wird. – ravron