মডিউল পাঠ (5/5)
`defer`: গ্যারান্টিযুক্ত পরিষ্কার
defer একটি কল কার্যকর করা স্থগিত করে এনক্লোসিং ফাংশন পর্যন্ত
ফেরত দেয়। প্যানিকের মাধ্যমে ফাংশনটি প্রস্থান করলেও এটি চলে। একাধিক defers
একই ফাংশনে LIFO অর্ডারে (লাস্ট-ইন, ফার্স্ট-আউট) চালান।
এটি রিসোর্স ক্লিনআপ-এর জন্য ইডিওম্যাটিক মেকানিজম: ফাইল বন্ধ করা, মিউটেক্স আনলক করা, সংযোগ রিলিজ করা, অবস্থা পুনরুদ্ধার করা।
সিনট্যাক্স এবং ক্যানোনিকাল ব্যবহারের ক্ষেত্রে
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close() // chiamata SEMPRE all'uscita della funzione
// ... usa f liberamente ...
return nilসাধারণ: f.Close(), mu.Unlock(), db.Close(), tx.Rollback(),
recover()
আর্গুমেন্ট অবিলম্বে মূল্যায়ন, মৃত্যুদন্ড স্থগিত
আপনি যখন defer foo(x) লেখেন, তখন x মূল্যায়ন করা হয়
defer_, কার্যকর করার সময় নয়:
x := 10
defer fmt.Println(x) // cattura 10
x = 99
// quando la funzione ritorna stampa "10", non "99"LIFO অর্ডার
সবচেয়ে সাম্প্রতিক দিয়ে শুরু করে স্ট্যাক আপ এবং এক্সিকিউট ডিফার করে:
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
// output: 3, 2, 1এটি রিসোর্স শব্দার্থবিদ্যার সাথে সামঞ্জস্যপূর্ণ: শেষ খোলা প্রথমটি বন্ধ করা
defer + recover: আতঙ্ক নিয়ন্ত্রণ করা
defer হল একটি panic বাধা দেওয়ার একমাত্র উপায়:
func safe() {
defer func() {
if r := recover(); r != nil {
fmt.Println("recuperato:", r)
}
}()
panic("boom")
}পিটফল: defer একটি লুপে
defer f.Close() কে একটি লুপে রাখলে ** শেষ না হওয়া পর্যন্ত স্থগিত হয়
ফাংশন**, প্রতিটি পুনরাবৃত্তির নয়। একটি দীর্ঘ লুপে আপনি অনেক ফাইল খুলুন
এবং শুধুমাত্র যখন ফাংশন প্রস্থান করে তখনই সেগুলি বন্ধ করুন: ফাইল বর্ণনাকারী ফাঁসের ঝুঁকি৷
// MALE: defer accumulati
for _, path := range paths {
f, _ := os.Open(path)
defer f.Close() // chiude TUTTI alla fine della funzione esterna
// ...
}
// MEGLIO: estrai in una funzione
for _, path := range paths {
elabora(path) // ogni chiamata ha il proprio scope di defer
}চেষ্টা করে দেখুন
'inizio' প্রিন্ট করুন, তারপর defer দিয়ে 'fine'-এর প্রিন্ট ডিফার করুন, তারপর 'mezzo' প্রিন্ট করুন। আউটপুট হতে হবে: inizio/mezzo/fine.
ইঙ্গিত দেখান
যখন main() ফিরতে চলেছে তখন defer চলে।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
কোডে সেই ক্রমে 1, 2 এবং 3 প্রিন্ট করে এমন তিনটি পরপর ডিফার লিখুন। আউটপুট হবে 3/2/1 (LIFO)।
ইঙ্গিত দেখান
ক্রম তিনটি defers; মনে রাখবেন তারা বিপরীত ক্রমে চালায়।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
এই মুদ্রণ কি? (দ্রষ্টব্য: বিলম্বিত আর্গুমেন্ট অবিলম্বে মূল্যায়ন করা হয়)
x := 10
defer fmt.Println(x)
x = 99রিক্যাপ
defer call()ফাংশন ফিরে না আসা পর্যন্ত এক্সিকিউশন স্থগিত করে।- একাধিক ডিফার = LIFO অর্ডার।
- যুক্তি অবিলম্বে মূল্যায়ন করা হয়েছে, মৃত্যুদন্ড স্থগিত করা হয়েছে।
- নির্ধারক পরিষ্কারের জন্য ব্যবহৃত হয়: ফাইল, মিউটেক্স, সংযোগ।
defer+recover()একটিpanicবাধা দেয় (বিরল, সীমানায়)।- একটি দীর্ঘ লুপের ভিতরে
deferকখনই নয়: বাইরের ফাংশনটি ফিরে না আসা পর্যন্ত এটি জমা হয়।