2016-01-09 5 views
6

जब 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 _ 

क्यों है उस में एक परिवर्तनशील कच्चे सूचक करने के लिए दो डाले प्रदर्शन के लिए आवश्यक एक पंक्ति? एक बार केवल एक बार कास्ट करने के लिए पर्याप्त क्यों नहीं होगा?

उत्तर

7

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 है ताकि प्रकार &mut libc::timeval की है

&mut timeout as *mut _ as *mut _ 

पहले: अब हम विचार करते हैं। फिर आप as *mut _ को अनुमानित प्रकार के कच्चे म्यूटेबल पॉइंटर पर केंद्रित करने के लिए करते हैं, जो इस मामले में libc::timeval का एक ही प्रकार है, इसलिए पूर्ण प्रकार अब तक है: *mut libc::timeval, जो पैरामीटर प्रकार *mut c_void से मेल नहीं खाता है। अंतिम as *mut _ फिर से लक्ष्य प्रकार का अनुमान लगाता है, जो अब पैरामीटर प्रकार *mut c_void है, इसलिए अंततः *mut libc::timeval को *mut c_void पर ले जाता है।

+0

आह, मुझे यह मिल गया। स्पष्टीकरण देने के लिए धन्यवाद! फॉलो-अप प्रश्न: क्या 'होटॉकॉप्टी' के हस्ताक्षर के कारण जंग दूसरे रूपांतरण को अनुमानित करता है या यह है कि अगर मैं अक्सर रूपांतरण करता हूं तो * प्रत्येक * सूचक को '* mut c_void' पर डाला जाता है? यहां तक ​​कि एक मनमाना मूल प्रकार के लिए, मान लें कि 'और mut Vec '? –

+0

नहीं, शुक्रिया नहीं! यह डरावना होगा: एस वास्तव में 'होटॉकॉप्टी' के हस्ताक्षर की वजह से है, विशेष रूप से क्योंकि अभिव्यक्ति की स्थिति में लक्ष्य प्रकार है। वही मामला होगा। यदि आप 'ptr: * mut c_void = और mut timeout * mut _ as * mut _;' के रूप में कर रहे थे। –

संबंधित मुद्दे