DeB*_*eBe 11 pointers casting rust
在查看时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
};
Run Code Online (Sandbox Code Playgroud)
我特别好奇这些线条:
&mut timeout as *mut _ as *mut _,
&mut size as *mut _ as *mut _
Run Code Online (Sandbox Code Playgroud)
为什么有必要对一行中的可变原始指针执行两次转换?为什么仅仅施放一次就不够了?
在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
Run Code Online (Sandbox Code Playgroud)
该timeout文件中的定义为:
let mut timeout: libc::timeval = mem::zeroed();
Run Code Online (Sandbox Code Playgroud)
所以这是类型libc::timeval.现在让我们考虑一下:
&mut timeout as *mut _ as *mut _
Run Code Online (Sandbox Code Playgroud)
首先你是&mut timeout这样的&mut libc::timeval.然后你as *mut _将它强制转换为推断类型的原始可变指针,在这种情况下它是相同的类型libc::timeval,所以到目前为止的完整类型是:*mut libc::timeval,它与参数类型不匹配*mut c_void.最后as *mut _再次推断目标类型,现在是参数类型*mut c_void,所以最终强制转换*mut libc::timeval为a *mut c_void.