Go में स्लाइस दूसरी भाषाओं के ऐरे जैसे होते हैं। इनमें किसी खास टाइप (या इंटरफ़ेस) के कई एलिमेंट रहते हैं।
Go में स्लाइस ऐरे पर आधारित होते हैं। ऐरे का आकार निश्चित होता है। दूसरी ओर, स्लाइस ऐरे के एलिमेंट्स का एक गतिशील आकार वाला, लचीला दृश्य होता है।
स्लाइस को []T की तरह लिखा जाता है, जहाँ T स्लाइस के एलिमेंट्स का टाइप होता है:
var empty []int // an empty slice
withData := []int{0,1,2,3,4,5} // a slice pre-filled with some data
आप चौकोर ब्रैकेट का उपयोग करके किसी दिए गए शून्य-आधारित इंडेक्स पर एलिमेंट पा सकते हैं या सेट कर सकते हैं:
withData[1] = 5
x := withData[1] // x is now 5
आप किसी मौजूदा स्लाइस से एलिमेंट्स की एक रेंज लेकर नया स्लाइस बना सकते हैं। फिर से चौकोर ब्रैकेट का उपयोग करके, लेकिन इस बार शुरुआती (शामिल) और अंतिम (शामिल नहीं) दोनों इंडेक्स बताकर। अगर आप शुरुआती इंडेक्स नहीं बताते, तो वह डिफ़ॉल्ट रूप से 0 हो जाता है। अगर आप अंतिम इंडेक्स नहीं बताते, तो वह डिफ़ॉल्ट रूप से स्लाइस की लंबाई हो जाता है।
newSlice := withData[2:4]
// => []int{2,3}
newSlice := withData[:2]
// => []int{0,1}
newSlice := withData[2:]
// => []int{2,3,4,5}
newSlice := withData[:]
// => []int{0,1,2,3,4,5}
आप append फंक्शन का उपयोग करके स्लाइस में एलिमेंट्स जोड़ सकते हैं।
नीचे हम a स्लाइस में 4 और 2 जोड़ते हैं।
a := []int{1, 3}
a = append(a, 4, 2)
// => []int{1,3,4,2}
append हमेशा एक नया स्लाइस लौटाता है। जब हमें किसी मौजूदा स्लाइस में एलिमेंट्स जोड़ने हों, तो आम तौर पर उसे उसी स्लाइस वेरिएबल को फिर से असाइन कर दिया जाता है जिसे हम पहला आर्गुमेंट बनाकर पास करते हैं, जैसा ऊपर किया गया है।
append का उपयोग दो स्लाइस मिलाने के लिए भी किया जा सकता है:
nextSlice := []int{100,101,102}
newSlice := append(withData, nextSlice...)
// => []int{0,1,2,3,4,5,100,101,102}
आम तौर पर Go में फंक्शन केवल एक निश्चित संख्या में आर्गुमेंट लेते हैं। लेकिन Go में वेरिएडिक फंक्शन लिखना भी संभव है।
वेरिएडिक फंक्शन एक ऐसा फंक्शन है जो कितने भी आर्गुमेंट ले सकता है।
अगर किसी फंक्शन की परिभाषा में आखिरी पैरामीटर के टाइप से पहले एलिप्सिस ... लगा हो, तो फंक्शन उस पैरामीटर के लिए कितने भी आर्गुमेंट ले सकता है।
func find(a int, b ...int) {
// ...
}
ऊपर के फंक्शन में पैरामीटर b वेरिएडिक है और हम b को 0 या उससे अधिक आर्गुमेंट पास कर सकते हैं।
find(5, 6)
find(5, 6, 7)
find(5)
वेरिएडिक पैरामीटर फंक्शन का आखिरी पैरामीटर होना चाहिए।
वेरिएडिक फंक्शन काम करने का तरीका यह है कि बदलती संख्या के आर्गुमेंट को वेरिएडिक पैरामीटर के टाइप वाले स्लाइस में बदल दिया जाता है।
यहाँ एक वेरिएडिक फंक्शन के इम्प्लीमेंटेशन का उदाहरण है।
func find(num int, nums ...int) {
fmt.Printf("type of nums is %T\n", nums)
for i, v := range nums {
if v == num {
fmt.Println(num, "found at index", i, "in", nums)
return
}
}
fmt.Println(num, "not found in ", nums)
}
func main() {
find(89, 90, 91, 95)
// =>
// type of nums is []int
// 89 not found in [90 91 95]
find(45, 56, 67, 45, 90, 109)
// =>
// type of nums is []int
// 45 found at index 2 in [56 67 45 90 109]
find(87)
// =>
// type of nums is []int
// 87 not found in []
}
ऊपर के प्रोग्राम की find(89, 90, 91, 95) लाइन में, find फंक्शन को दिए गए बदलती संख्या वाले आर्गुमेंट 90, 91 और 95 हैं।
find फंक्शन num के बाद एक वेरिएडिक int पैरामीटर की अपेक्षा करता है।
इसलिए कंपाइलर इन तीनों आर्गुमेंट को int टाइप के स्लाइस []int{90, 91, 95} में बदल देगा और फिर उसे find फंक्शन को nums के रूप में पास करेगा।
कभी-कभी आपके पास पहले से एक स्लाइस होता है और आप उसे किसी वेरिएडिक फंक्शन को पास करना चाहते हैं।
यह स्लाइस के बाद ... लगाकर पास करने से किया जा सकता है।
इससे कंपाइलर को पता चलेगा कि वेरिएडिक फंक्शन के अंदर स्लाइस का जैसा है वैसा ही उपयोग करना है।
ऊपर बताया गया वह चरण, जहाँ एक स्लाइस बनाया जाता है, इस मामले में बस छोड़ दिया जाएगा।
list := []int{1, 2, 3}
find(1, list...) // "find" defined as shown above
भावी जादूगर Elyse को कुछ बुनियादी चीज़ों का अभ्यास करना है। उसके पास कार्ड का एक ढेर है, जिसके साथ वह तरह-तरह के काम करना चाहती है।
काम को थोड़ा आसान बनाने के लिए वह सिर्फ 1 से 10 तक के कार्ड इस्तेमाल करती है।
कार्डों के साथ अभ्यास करते समय Elyse को अपने सबसे पसंदीदा तीन कार्डों से शुरू करना अच्छा लगता है: 2, 6 और 9। एक फंक्शन FavoriteCards लिखिए जो उन कार्डों को उसी क्रम में रखते हुए एक स्लाइस लौटाता है।
cards := FavoriteCards()
fmt.Println(cards)
// Output: [2 6 9]
दिए गए ढेर में index स्थान पर रखा कार्ड लौटाइए।
card := GetItem([]int{1, 2, 4, 1}, 2) // card == 4
अगर index सीमा से बाहर हो (यानी ऋणात्मक हो या ढेर के अंत से आगे चला जाए), तो हमें -1 लौटाना है:
card := GetItem([]int{1, 2, 4, 1}, 10) // card == -1
Go में परंपरा यह है कि "सीमा से बाहर" वाली वैल्यू लौटाने की जगह एक एरर लौटाई जाती है। यहाँ "सीमा से बाहर" वाली वैल्यू -1 है, जबकि अपेक्षा एक धनात्मक पूर्णांक की होती है। एरर लौटाते समय उसके साथ zero value लौटाना ही Go का स्वाभाविक तरीका माना जाता है। सही रिटर्न वैल्यू के साथ एरर लौटाने की बात आगे किसी अभ्यास में बताई जाएगी।
index स्थान पर रखे कार्ड को दिए गए नए कार्ड से बदल दीजिए और बदला हुआ ढेर लौटाइए। ध्यान रखिए कि इससे इनपुट स्लाइस में बदलाव होगा, और यही अपेक्षित व्यवहार है।
index := 2
newCard := 6
cards := SetItem([]int{1, 2, 4, 1}, index, newCard)
fmt.Println(cards)
// Output: [1 2 6 1]
अगर index सीमा से बाहर हो (यानी ऋणात्मक हो या ढेर के अंत से आगे चला जाए), तो हमें नया कार्ड ढेर के अंत में जोड़ना है:
index := -1
newCard := 6
cards := SetItem([]int{1, 2, 4, 1}, index, newCard)
fmt.Println(cards)
// Output: [1 2 4 1 6]
value पैरामीटर में दिए गए कार्ड ढेर के सबसे ऊपर जोड़िए।
slice := []int{3, 2, 6, 4, 8}
cards := PrependItems(slice, 5, 1)
fmt.Println(cards)
// Output: [5 1 3 2 6 4 8]
अगर value पैरामीटर के लिए कोई आर्गुमेंट नहीं दिया गया हो, तो परिणाम मूल स्लाइस के बराबर होता है।
slice := []int{3, 2, 6, 4, 8}
cards := PrependItems(slice)
fmt.Println(cards)
// Output: [3 2 6 4 8]
index स्थान पर रखा कार्ड ढेर से हटाइए और ढेर लौटाइए। ध्यान रखिए कि इससे इनपुट स्लाइस में बदलाव हो सकता है, और इसमें कोई दिक्कत नहीं है।
cards := RemoveItem([]int{3, 2, 6, 4, 8}, 2)
fmt.Println(cards)
// Output: [3 2 4 8]
अगर index सीमा से बाहर हो (यानी ऋणात्मक हो या ढेर के अंत से आगे चला जाए), तो हमें ढेर को बिना बदले छोड़ देना है:
cards := RemoveItem([]int{3, 2, 6, 4, 8}, 11)
fmt.Println(cards)
// Output: [3 2 6 4 8]
Exercism पर साइन अप कीजिए और Go को 34 कॉन्सेप्ट165 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।