2015-05-21 6 views
5

rustc 1.0.0 में, मैं एक ऐसा फ़ंक्शन लिखना चाहता हूं जो कॉलर द्वारा प्रदान की गई दो आयामी सरणी को उत्परिवर्तित करे। मुझे उम्मीद थी इस काम करेगा:एक फंक्शन तर्क के रूप में उत्परिवर्तनीय बहुआयामी सरणी

fn foo(x: &mut [[u8]]) { 
    x[0][0] = 42; 
} 

fn main() { 
    let mut x: [[u8; 3]; 3] = [[0; 3]; 3]; 
    foo(&mut x); 
} 

यह संकलन करने में विफल रहता है:

$ rustc fail2d.rs 
fail2d.rs:7:9: 7:15 error: mismatched types: 
expected `&mut [[u8]]`, 
    found `&mut [[u8; 3]; 3]` 
(expected slice, 
    found array of 3 elements) [E0308] 
fail2d.rs:7  foo(&mut x); 
        ^~~~~~ 
error: aborting due to previous error 

मेरा मानना ​​है कि यह कह रहा है कि मैं किसी भी तरह समारोह स्लाइस का एक टुकड़ा को खिलाने के लिए की जरूरत है, लेकिन मैं नहीं जानता कि इसे कैसे बनाया जाए।

यदि मैं फ़ंक्शन हस्ताक्षर में नेस्टेड सरणी की लंबाई को हार्ड-कोड करता हूं तो यह "काम करता है"। यह स्वीकार्य है क्योंकि मैं समारोह मनमाना आयाम की बहुआयामी सरणियों पर काम करना चाहते हैं नहीं है:

fn foo(x: &mut [[u8; 3]]) { // FIXME: don't want to hard code length of nested array 
    x[0][0] = 42; 
} 

fn main() { 
    let mut x: [[u8; 3]; 3] = [[0; 3]; 3]; 
    foo(&mut x); 
} 

tldr; एक बहुआयामी सरणी के संदर्भ को पारित करने के किसी भी शून्य-लागत के तरीके जैसे कि फ़ंक्शन का उपयोग $ x [1] [2] = 3; $?

+0

आपको https://github.com/rust-lang/rfcs/issues/1038 और सामान्य मूल्य पैरामीटर के बारे में संबंधित पीआर में रुचि हो सकती है –

उत्तर

6

यह मेमोरी लेआउट के मामले में आता है। T को संकलित समय पर ज्ञात आकार के साथ मानते हैं (यह बाधा T: Sized लिखा जा सकता है), [T; n] का आकार संकलन समय पर जाना जाता है (nT करता है जितनी बार मेमोरी लेता है); लेकिन [T] एक अनसुलझा प्रकार है; इसकी लंबाई संकलन समय पर ज्ञात नहीं है। इसलिए इसका उपयोग केवल कुछ प्रकार के संकेतों के माध्यम से किया जा सकता है, जैसे एक संदर्भ() या एक बॉक्स (Box<[T]>, हालांकि यह Vec<T> के साथ सीमित व्यावहारिक मूल्य है, जो आपको हर बार फिर से आवंटित किए बिना आइटम जोड़ने और हटाने की अनुमति देता है समग्र स्थान का उपयोग करके)।

एक अनसुलझा प्रकार का एक टुकड़ा समझ में नहीं आता है; यह ने को उन कारणों के लिए अनुमति दी है जो मुझे स्पष्ट नहीं हैं, लेकिन आप वास्तव में इसका कोई उदाहरण नहीं ले सकते हैं। (Vec<T> तुलनात्मक रूप से, T: Sized की आवश्यकता है।)

&[T; n]&[T] लिए मजबूर कर सकते हैं और &mut [T] को &mut [T; n], लेकिन यह केवल सबसे बाहरी स्तर पर लागू होता है; टुकड़ा की सामग्री तय की गई है (आपको इस तरह के परिवर्तन को प्राप्त करने के लिए एक नई सरणी या वेक्टर बनाना होगा, क्योंकि प्रत्येक आइटम का मेमोरी लेआउट अलग है)। इसका प्रभाव यह है कि सरणी एकल-आयामी काम के लिए काम करती हैं, लेकिन बहु-आयामी काम के लिए वे अलग हो जाते हैं। एरे वर्तमान में जंग में बहुत अधिक द्वितीय श्रेणी के नागरिक हैं, और जब तक भाषा लंबाई से सामान्य रूप से स्लाइस बनाने में सहायता नहीं करती है, जो अंत में होने की संभावना है।

मैं अनुशंसा करता हूं कि आप या तो एकल-आयामी सरणी (स्क्वायर मैट्रिस के लिए उपयुक्त, x * width + y या इसी तरह से अनुक्रमित), या वैक्टर (Vec<Vec<T>>) का उपयोग करें। उपयुक्त समाधान पर सारणित होने से पहले पुस्तकालय भी हो सकते हैं।

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