2015-09-06 13 views
5

मैं समझने की कोशिश कर रहा हूं कि उचित जंग कोड कैसे लिखना है, लेकिन मुझे लगता है कि मैं अपने ऑब्जेक्ट्स के जीवनकाल को समझने के लिए कंपाइलर की क्षमता की शक्ति को अधिक महत्व दे सकता हूं।मैं फ़ंक्शन से एक पथ कैसे वापस कर सकता हूं?

use std::path::Path; 
use std::env; 
use rusqlite::SqliteConnection; 

struct SomeDatabase { 
    conn: SqliteConnection, 
} 

impl SomeDatabase { 
    fn getPath() -> &Path { 
     let path = env::home_dir().unwrap(); 
     path.push("foo.sqlite3"); 
     path.as_path() 
    } 

    fn open() -> SomeDatabase { 
     let path = SomeDatabase::getPath() 
     SomeDatabase { conn: SqliteConnection::open(path).unwrap() } 
    } 
} 

fn main() { 
    let db = SomeDatabase::open(); 
} 

जब मैं इस संकलन करने का प्रयास करें, मैं &Path पर एक लापता जीवनकाल विनिर्देशक के बारे में त्रुटि: यह कोड मैं यह काम करने की उम्मीद के रूप में है। मुझे पता है कि क्या यह कॉलर से संदर्भ पैरामीटर लेता है, यह उस संदर्भ के समान जीवनकाल लेगा। यहां हालांकि मैं जो उम्मीद कर रहा था वह यह है कि जीवनकाल उस चर से जुड़ा होगा जिसे मैं परिणाम दे रहा हूं।

मुझे पता है कि जीवनकाल स्पष्ट रूप से जोड़ा जा सकता है, लेकिन मुझे नहीं पता कि इस मामले में उन्हें कैसे लागू किया जाए। संकलक 'static जीवनकाल की कोशिश करने का सुझाव देता है, लेकिन जहां तक ​​मुझे पता है कि यह इस बात का अर्थ नहीं है क्योंकि इस फ़ंक्शन के वापसी मूल्य का स्रोत स्थिर नहीं है।

अब, बस देखने के लिए कि मैं कोड के बाकी को संकलित करने की कोशिश की कि क्या हुआ की कोशिश करना, मैं PathBuf को &Path से वापसी प्रकार बदल गया है और open() में as_path() कहा जाता है। इस उत्पादन के लिए संकलक इन त्रुटियों के कारण होता है:

src\main.rs:22:30: 22:52 error: the trait `core::marker::Sized` is not implemented for the type `[u8]` [E0277] 
src\main.rs:22   SomeDatabase { conn: SqliteConnection::open(path).unwrap() } 
              ^~~~~~~~~~~~~~~~~~~~~~ 
src\main.rs:22:30: 22:52 note: `[u8]` does not have a constant size known at compile-time 
src\main.rs:22   SomeDatabase { conn: SqliteConnection::open(path).unwrap() } 
              ^~~~~~~~~~~~~~~~~~~~~~ 

SqliteConnection::open() रिटर्न एक Result<SqliteConnection, SqliteError> और SqliteConnection अंदर ही क्षेत्र एक RefCell है, इसलिए मुझे समझ नहीं आता जहां एक बाइट सरणी के बारे में इस त्रुटि से आ रही है।

तो, मैं क्यों काम नहीं कर रहा हूं और इस कोड को लिखने का सबसे जंगली तरीका क्यों है?

उत्तर

7

आपके पहले मामले में, आप एक मूल्य बना रहे हैं और फिर इसके संदर्भ को वापस करने का प्रयास कर रहे हैं। लेकिन चूंकि आप कहीं भी उस मूल्य को संग्रहीत नहीं कर रहे हैं, इसलिए फ़ंक्शन समाप्त होने के बाद यह नष्ट हो जाता है। अगर इसकी अनुमति थी, तो यह एक प्रयोग-बाद-मुक्त बग होगा।

&'static Path लौटने का सुझाव देने का कारण यह है कि फ़ंक्शन किसी भी जीवनकाल में पैरामीटर नहीं किया गया है, इसलिए केवल एक ही जीवनकाल आप सुनिश्चित कर सकते हैं कि वापसी मूल्य का उपयोग करना चाहते हैं, जो कुछ भी 'static होगा।

आप सही हैं कि आपको के बजाय सीधे PathBuf वापस करने की आवश्यकता है।

मुझे पूरा यकीन नहीं है कि आपको [u8] आकार की त्रुटियां क्यों मिल रही हैं।

आपको "as_path()" बिल्कुल कॉल करने की आवश्यकता नहीं है। SqliteConnection::open एक मान लेता है जो AsRef<Path> लागू करता है (AsRefInto की तरह है), और PathBuf उस विशेषता को लागू करता है।

+0

मुझे एहसास है कि पहले मामले में मैं फ़ंक्शन के अंदर बनाई गई किसी चीज़ का संदर्भ वापस कर रहा हूं, लेकिन अगर मैं GetPath() को कुछडेटाबेस का सदस्य फ़ंक्शन बनाता हूं, तो संकलक कुछ डेटाबेस के उदाहरण तक पथ और पकड़ने के लिए पर्याप्त स्मार्ट है गुंजाइश से बाहर चला जाता है। मैं पूछ रहा हूं कि संकलक को बताने का कोई तरीका है कि संदर्भ का जीवनकाल उस फ़ंक्शन से संबंधित है जो GetPath() को कॉल कर रहा है (उस स्थिति में जहां GetPath() एक संबद्ध फ़ंक्शन है)। यह आजीवन कोड तब तक होना चाहिए जब संदर्भ को धारण करने के लिए खुले() में दायरे से बाहर हो। –

+0

यह भी जोड़ना है कि अगर मैं as_path() को छोड़ देता हूं, तो मुझे एक बेमेल प्रकार त्रुटि मिलती है: "अपेक्षित 'और _', 'std :: path :: pathbuf' (अपेक्षित और -ptr, मिली स्ट्रक्चर 'std :: path :: PathBuf ') –

+1

@AustinWagner परिवर्तनीय' पथ' को 'getPath()' विधि के शरीर में परिभाषित किया गया है, इसका कार्यकाल इस कार्य निकाय के दायरे के अंत में समाप्त होता है, जब तक कि आप इसे वापस नहीं करते। कोई रास्ता नहीं है इस नियम से बचने के लिए। आपके मामले में 'getPath()' फ़ंक्शन के लिए 'पथबफ' को वापस करने का कोई विकल्प नहीं है। – Levans

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

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