dispatch IO channelを使用して、ファイル記述子から一部のデータを読みたいとします。チャンネルを作成したら、次のステップは、その宣言は次のようであるread
を呼び出すことです:Swift GCDオーバーレイでのタイプの不一致
func read(offset: off_t,
length: Int,
queue: DispatchQueue,
ioHandler: @escaping (Bool, DispatchData?, Int32) -> Void)
length
パラメータのドキュメントは言う:
The number of bytes to read from the channel. Specify SIZE_MAX to continue reading data until an EOF is reached.
は十分に簡単に思えます。私の場合、私はちょうどそれをしたいです - EOFまで読む。だから私はSIZE_MAX
を渡します:
// `queue` and `handler` defined elsewhere
channel.read(offset: 0, length: SIZE_MAX, queue: queue, ioHandler: handler)
賢明な読者は、コンパイラはこれを好きではないことを推測しています
Cannot convert value of type 'UInt' to expected argument type 'Int'
SIZE_MAX
タイプUInt
のですが、length
はタイプInt
です。コンパイラはそれを修正するために提供しています:
channel.read(offset: 0, length: Int(SIZE_MAX), queue: queue, ioHandler: handler)
しかし、もちろん、実行時に、これはとてもうまく動作しません:
fatal error: Not enough bits to represent a signed value
を当然SIZE_MAX
がUInt
によって最大値の表現であれば、その後、Int
それを表現することはできません。いくつかのクイック検索の後、私はthis exact issue on the Swift bug trackerを見つけました。それはまだ解決されていないようで、プルリクエストで自分自身で解決する能力が不明です。どうすればこの問題を回避できますか?それとも、私が欲しいことをするための方法が欠けていますか?
スウィフトStdlibの理論的根拠ドキュメントcovers the explicit decision to import size_t
as Int
rather than UInt
。 「より少ないタイプの変換」と、とにかく2^63を超える数を指定する必要がある(残念ながら、32ビットプラットフォーム)。十分に公正ですが、それはSIZE_MAX
の使用がAPIの一部である私のような問題をカバーしません。
'length:Int(bitPattern:SIZE_MAX)'を渡しても問題ありませんか? –
それかもしれません!少なくともコンパイルしてもクラッシュしません。正直なところ、私はまだこれをテストする合理的な方法を考え出していない。私は正確に2^64バイトのデータストリームを作成することはできませんし、SwiftからCへのインターフェイスで 'Int'が' size_t'にどのように変換されるのかについての実体的な扱いはありません。 – ravron