在查看unix-socket
时,我发现了这段代码:
let timeout = unsafe {
let mut timeout: libc::timeval = mem::zeroed();
let mut size = mem::size_of::<libc::timeval>() as libc::socklen_t;
try!(cvt(libc::getsockopt(self.0,
libc::SOL_SOCKET,
kind,
&mut timeout as *mut _ as *mut _,
&mut size as *mut _ as *mut _)));
timeout
};
我特别好奇这些界限:
&mut timeout as *mut _ as *mut _,
&mut size as *mut _ as *mut _
为什么有必要对一行中的可变原始指针执行两次转换?为什么仅仅施放一次就不够了?
答案 0 :(得分:9)
timeout
例如对应*mut c_void
参数:
pub unsafe extern fn getsockopt(sockfd: c_int, level: c_int, optname: c_int,
optval: *mut c_void, optlen: *mut socklen_t) -> c_int
该文件中的timeout
定义为:
let mut timeout: libc::timeval = mem::zeroed();
所以类型为libc::timeval
。现在让我们考虑一下:
&mut timeout as *mut _ as *mut _
首先,您有&mut timeout
,因此类型为&mut libc::timeval
。然后你执行as *mut _
将它强制转换为推断类型的原始可变指针,在这种情况下它是libc::timeval
的相同类型,所以到目前为止的完整类型是:*mut libc::timeval
,与参数类型*mut c_void
不匹配。最后的as *mut _
再次推断出目标类型,现在是参数类型*mut c_void
,因此最终会将*mut libc::timeval
强制转换为*mut c_void
。