Swift GCD 覆盖中的类型不匹配
Type mismatch in Swift GCD overlay
我想用一个dispatch IO channel to read some data from a file descriptor. After creating the channel, the next step is to call read
,它的声明如下:
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)
精明的reader猜到编译器不喜欢这样:
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。因为它似乎还没有得到解决——而且我不确定我自己是否有能力通过拉取请求来解决它——我该如何解决这个问题?还是我错过了一种方法来做我想做的事?
Swift Stdlib 基本原理文档 covers the explicit decision to import size_t
as Int
rather than UInt
。它归结为 "fewer type conversions, and who needs to specify numbers above 2^63 anyways (sorry, 32-bit platforms)." 足够公平,但这不包括像我这样的问题,其中 SIZE_MAX
的使用是 API.
的一部分
只需使用 Int.max
如果您在 64 位平台上,您仍然几乎可以保证在读取 Int.max
字节之前到达文件末尾。在 32 位平台上,如果您的文件非常大,您可能需要发出多次读取。
那你应该向Apple报告这个问题。我不确定 Dispatch IO 库是属于 Apple 还是 Swift 开源项目,或者它是否只是一个文档错误。
更新
源代码是开源的,读取操作只是对长度为size_t
的C函数的简单包装。
https://github.com/apple/swift-corelibs-libdispatch/blob/master/src/swift/IO.swift
我没试过,但你几乎可以肯定地使用位模式,甚至可能 -1
。不过我想我还是会选择 Int.max
。
我想用一个dispatch IO channel to read some data from a file descriptor. After creating the channel, the next step is to call read
,它的声明如下:
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)
精明的reader猜到编译器不喜欢这样:
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。因为它似乎还没有得到解决——而且我不确定我自己是否有能力通过拉取请求来解决它——我该如何解决这个问题?还是我错过了一种方法来做我想做的事?
Swift Stdlib 基本原理文档 covers the explicit decision to import size_t
as Int
rather than UInt
。它归结为 "fewer type conversions, and who needs to specify numbers above 2^63 anyways (sorry, 32-bit platforms)." 足够公平,但这不包括像我这样的问题,其中 SIZE_MAX
的使用是 API.
只需使用 Int.max
如果您在 64 位平台上,您仍然几乎可以保证在读取 Int.max
字节之前到达文件末尾。在 32 位平台上,如果您的文件非常大,您可能需要发出多次读取。
那你应该向Apple报告这个问题。我不确定 Dispatch IO 库是属于 Apple 还是 Swift 开源项目,或者它是否只是一个文档错误。
更新
源代码是开源的,读取操作只是对长度为size_t
的C函数的简单包装。
https://github.com/apple/swift-corelibs-libdispatch/blob/master/src/swift/IO.swift
我没试过,但你几乎可以肯定地使用位模式,甚至可能 -1
。不过我想我还是会选择 Int.max
。