Go by Example : Slices
Next example: Maps .
by Mark McGranaghan and Eli Bendersky | source | license
The Go Blog
Go slices: usage and internals.
Andrew Gerrand 5 January 2011
Introduction
Go's slice type provides a convenient and efficient means of working with sequences of typed data. Slices are analogous to arrays in other languages, but have some unusual properties. This article will look at what slices are and how they are used.
The slice type is an abstraction built on top of Go's array type, and so to understand slices we must first understand arrays.
An array type definition specifies a length and an element type. For example, the type [4]int represents an array of four integers. An array's size is fixed; its length is part of its type ( [4]int and [5]int are distinct, incompatible types). Arrays can be indexed in the usual way, so the expression s[n] accesses the nth element, starting from zero.
Arrays do not need to be initialized explicitly; the zero value of an array is a ready-to-use array whose elements are themselves zeroed:
The in-memory representation of [4]int is just four integer values laid out sequentially:
Go's arrays are values. An array variable denotes the entire array; it is not a pointer to the first array element (as would be the case in C). This means that when you assign or pass around an array value you will make a copy of its contents. (To avoid the copy you could pass a pointer to the array, but then that's a pointer to an array, not an array.) One way to think about arrays is as a sort of struct but with indexed rather than named fields: a fixed-size composite value.
An array literal can be specified like so:
Or, you can have the compiler count the array elements for you:
In both cases, the type of b is [2]string .
Arrays have their place, but they're a bit inflexible, so you don't see them too often in Go code. Slices, though, are everywhere. They build on arrays to provide great power and convenience.
The type specification for a slice is []T , where T is the type of the elements of the slice. Unlike an array type, a slice type has no specified length.
A slice literal is declared just like an array literal, except you leave out the element count:
A slice can be created with the built-in function called make , which has the signature,
where T stands for the element type of the slice to be created. The make function takes a type, a length, and an optional capacity. When called, make allocates an array and returns a slice that refers to that array.
When the capacity argument is omitted, it defaults to the specified length. Here's a more succinct version of the same code:
The length and capacity of a slice can be inspected using the built-in len and cap functions.
The next two sections discuss the relationship between length and capacity.
The zero value of a slice is nil . The len and cap functions will both return 0 for a nil slice.
A slice can also be formed by "slicing" an existing slice or array. Slicing is done by specifying a half-open range with two indices separated by a colon. For example, the expression b[1:4] creates a slice including elements 1 through 3 of b (the indices of the resulting slice will be 0 through 2).
The start and end indices of a slice expression are optional; they default to zero and the slice's length respectively:
This is also the syntax to create a slice given an array:
Slice internals
A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment).
Our variable s , created earlier by make([]byte, 5) , is structured like this:
The length is the number of elements referred to by the slice. The capacity is the number of elements in the underlying array (beginning at the element referred to by the slice pointer). The distinction between length and capacity will be made clear as we walk through the next few examples.
As we slice s , observe the changes in the slice data structure and their relation to the underlying array:
Slicing does not copy the slice's data. It creates a new slice value that points to the original array. This makes slice operations as efficient as manipulating array indices. Therefore, modifying the elements (not the slice itself) of a re-slice modifies the elements of the original slice:
Earlier we sliced s to a length shorter than its capacity. We can grow s to its capacity by slicing it again:
A slice cannot be grown beyond its capacity. Attempting to do so will cause a runtime panic, just as when indexing outside the bounds of a slice or array. Similarly, slices cannot be re-sliced below zero to access earlier elements in the array.
Growing slices (the copy and append functions)
To increase the capacity of a slice one must create a new, larger slice and copy the contents of the original slice into it. This technique is how dynamic array implementations from other languages work behind the scenes. The next example doubles the capacity of s by making a new slice, t , copying the contents of s into t , and then assigning the slice value t to s :
The looping piece of this common operation is made easier by the built-in copy function. As the name suggests, copy copies data from a source slice to a destination slice. It returns the number of elements copied.
The copy function supports copying between slices of different lengths (it will copy only up to the smaller number of elements). In addition, copy can handle source and destination slices that share the same underlying array, handling overlapping slices correctly.
Using copy , we can simplify the code snippet above:
A common operation is to append data to the end of a slice. This function appends byte elements to a slice of bytes, growing the slice if necessary, and returns the updated slice value:
One could use AppendByte like this:
Functions like AppendByte are useful because they offer complete control over the way the slice is grown. Depending on the characteristics of the program, it may be desirable to allocate in smaller or larger chunks, or to put a ceiling on the size of a reallocation.
But most programs don't need complete control, so Go provides a built-in append function that's good for most purposes; it has the signature
The append function appends the elements x to the end of the slice s , and grows the slice if a greater capacity is needed.
To append one slice to another, use ... to expand the second argument to a list of arguments.
Since the zero value of a slice ( nil ) acts like a zero-length slice, you can declare a slice variable and then append to it in a loop:
A possible "gotcha"
As mentioned earlier, re-slicing a slice doesn't make a copy of the underlying array. The full array will be kept in memory until it is no longer referenced. Occasionally this can cause the program to hold all the data in memory when only a small piece of it is needed.
For example, this FindDigits function loads a file into memory and searches it for the first group of consecutive numeric digits, returning them as a new slice.
This code behaves as advertised, but the returned []byte points into an array containing the entire file. Since the slice references the original array, as long as the slice is kept around the garbage collector can't release the array; the few useful bytes of the file keep the entire contents in memory.
To fix this problem one can copy the interesting data to a new slice before returning it:
A more concise version of this function could be constructed by using append . This is left as an exercise for the reader.
Further Reading
Effective Go contains an in-depth treatment of slices and arrays , and the Go language specification defines slices and their associated helper functions .
Related articles
- A new Go API for Protocol Buffers
- Working with Errors in Go 1.13
- Debugging what you deploy in Go 1.12
- HTTP/2 Server Push
- Introducing HTTP Tracing
- Generating code
- Arrays, slices (and strings): The mechanics of 'append'
- Introducing the Go Race Detector
- Go maps in action
- go fmt your code
- Organizing Go code
- Debugging Go programs with the GNU Debugger
- The Go image/draw package
- The Go image package
- The Laws of Reflection
- Error handling and Go
- First Class Functions in Go
- Profiling Go Programs
- A GIF decoder: an exercise in Go interfaces
- Introducing Gofix
- Godoc: documenting Go code
- Gobs of data
- C? Go? Cgo!
- JSON and Go
- Go Concurrency Patterns: Timing out, moving on
- Defer, Panic, and Recover
- Share Memory By Communicating
- JSON-RPC: a tale of interfaces
Instantly share code, notes, and snippets.
tetsuok / answer_pic.go
- Star 60 You must be signed in to star a gist
- Fork 9 You must be signed in to fork a gist
- Embed Embed this gist in your website.
- Share Copy sharable link for this gist.
- Clone via HTTPS Clone using the web URL.
- Learn more about clone URLs
waqasilyas commented Apr 8, 2021
Sorry, something went wrong.
Kenny50 commented Jun 13, 2021
Rubbybutton commented Jul 3, 2021
nazlicankurt commented Jan 6, 2022 • edited
SimZhou commented Feb 8, 2022
You guys are so creative
mankeheaven commented Mar 4, 2022
mohitajampala commented Apr 18, 2022 • edited
luigiraffale commented Apr 19, 2022
//Magnetic Field (properly, Magnetic Induction) around straight conductors, with currents flowing in opposite directions.
package main
import ( "math" //"fmt" "golang.org/x/tour/pic" )
func Pic(dx, dy int) (out [][]uint8) { for i := 0; i < dy; i++ { row := make([]uint8, dx) for j := range row { row[j] = uint8(Bfield(float64(i), float64(j))) } out = append(out, row) } return out }
func Bfield(xp, yp float64) (Bvalue float64) { const mu0 = 4e-7 * math.Pi //Vacuum permeability const mu = 0.5 * mu0 / math.Pi //Multiplicative Factor const I1, I2 = 8e4, -8e4 //current in conductors 1 & 2 const X1, Y1 = 128, 192 //abscissa, ordinate of conductor1 const X2, Y2 = 128, 64 //abscissa, ordinate of conductor2
func main() { pic.Show(Pic) }
andremarcondesteixeira commented May 3, 2022 • edited
dumindu commented May 5, 2022 • edited
The Simplest :)
DanNduati commented Jul 2, 2022 • edited
thomsebastin commented Jul 8, 2022 • edited
bradleyGamiMarques commented Jul 13, 2022
ericboy0224 commented Sep 17, 2022
moalghifari commented Oct 12, 2022 • edited
fatihayan61 commented Oct 29, 2022
JPCodaLot commented Dec 2, 2022
krapie commented Dec 6, 2022
odashi commented Dec 8, 2022
nreynis commented Mar 7, 2023
yongkangc commented Apr 3, 2023
package main import "math" import "golang.org/x/tour/pic" func Pic ( dx , dy int ) [][] uint8 { s := make ([][] uint8 , dy ) for y := range s { s [ y ] = make ([] uint8 , dx ) for x := range s [ y ] { s [ y ][ x ] = gopher ( x , y ) } } return s } func gopher ( x , y int ) uint8 { xx := float64 ( x ) yy := float64 ( y ) params := [][ 6 ] float64 { { 180 , 50 , 3 , 3 , 0 , 255 }, { 175 , 50 , 10 , 10 , 0 , 0 }, { 105 , 80 , 3 , 3 , 0 , 255 }, { 100 , 80 , 10 , 10 , 0 , 0 }, { 155 , 55 , 30 , 30 , 0 , 255 }, { 155 , 55 , 32 , 32 , 0 , 0 }, { 80 , 85 , 30 , 30 , 0 , 255 }, { 80 , 85 , 32 , 32 , 0 , 0 }, { 130 , 90 , 7 , 1 , 24 , 255 }, { 125 , 95 , 13 , 8 , 24 , 0 }, { 133 , 128 , 12 , 5 , 114 , 255 }, { 133 , 128 , 13 , 6 , 114 , 0 }, { 143 , 124 , 12 , 5 , 116 , 255 }, { 143 , 124 , 13 , 6 , 116 , 0 }, { 130 , 108 , 22 , 12 , 23 , 160 }, { 130 , 108 , 24 , 14 , 23 , 0 }, { 183 , 178 , 14 , 8 , - 20 , 255 }, { 183 , 178 , 15 , 9 , - 20 , 0 }, { 131 , 108 , 96 , 100 , 0 , 220 }, { 151 , 158 , 90 , 100 , 0 , 220 }, { 151 , 188 , 90 , 100 , 0 , 220 }, { 243 , 148 , 14 , 8 , - 20 , 255 }, { 243 , 148 , 15 , 9 , - 20 , 0 }, { 205 , 36 , 2 , 2 , 0 , 255 }, { 203 , 42 , 10 , 10 , 0 , 0 }, { 206 , 44 , 21 , 21 , 0 , 255 }, { 206 , 44 , 23 , 23 , 0 , 0 }, { 33 , 102 , 10 , 10 , 0 , 0 }, { 36 , 104 , 21 , 21 , 0 , 255 }, { 36 , 104 , 23 , 23 , 0 , 0 }, } for _ , p := range params { if judge ( xx , yy , p [ 0 ], p [ 1 ], p [ 2 ], p [ 3 ], p [ 4 ]) { return uint8 ( p [ 5 ]) } } return 255 } func judge ( x , y , cx , cy , a , b , deg float64 ) bool { t := deg * math . Pi / 180 ct := math . Cos ( t ) st := math . Sin ( t ) x2 := ( x - cx ) y2 := ( y - cy ) x3 := ( ct * x2 - st * y2 ) / a y3 := ( st * x2 + ct * y2 ) / b return x3 * x3 + y3 * y3 < 1 } func main () { pic . Show ( Pic ) }
this is amazing!
19valentin99 commented May 12, 2023
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 { img := make([][]uint8, dy) for y := range img { img[y] = make([]uint8, dx) for x := range img[y] { i := uint8(y) j := uint8(x)
Rivgad commented May 13, 2023
Mandelbrot set
Max95Cohen commented Sep 15, 2023
bryceleue commented Sep 16, 2023
mikurei commented Oct 12, 2023
Very suspicious pattern
hello2333 commented Feb 10, 2024
About Slices
Slices in Go are similar to lists or arrays in other languages. They hold several elements of a specific type (or interface).
Slices in Go are based on arrays. Arrays have a fixed size. A slice, on the other hand, is a dynamically-sized, flexible view of the elements of an array.
A slice is written like []T with T being the type of the elements in the slice:
You can get or set an element at a given zero-based index using the square-bracket notation:
You can create a new slice from an existing slice by getting a range of elements. Once again using square-bracket notation, but specifying both a starting (inclusive) and ending (exclusive) index. If you don't specify a starting index, it defaults to 0. If you don't specify an ending index, it defaults to the length of the slice.
You can add elements to a slice using the append function. Below we append 4 and 2 to the a slice.
append always returns a new slice, and when we just want to append elements to an existing slice, it's common to reassign it back to the slice variable we pass as the first argument as we did above.
append can also be used to merge two slices:
Indexes in slices
Working with indexes of slices should always be protected in some way by a check that makes sure the index actually exists. Failing to do so will crash the entire application.
Empty slices
nil -slices are the default empty slice. They have no drawbacks towards a slice with no values in them. The len function works on nil -slices, items can be added without initializing it, and so on. If creating a new slice prefer var s []int ( nil -slice) over s := []int{} (empty, non- nil slice).
Performance
When creating slices to be filled iteratively, there is a low-hanging fruit to improve performance, if the final size of the slice is known. The key is to minimize the number of times memory has to be allocated, which is rather expensive and happens if the slice grows beyond its allocated memory space. The safest way to do this is to specify a capacity cap for the slice with s := make([]int, 0, cap) and then append to the slice as usual. This way the space for cap amount of items is allocated immediately while the slice length is zero. In practice, cap is often the length of another slice: s := make([]int, 0, len(otherSlice)) .
Append is not a pure function
The append function of Go is optimized for performance and therefore does not make a copy of the input slice. This means that the original slice (1st parameter in append ) will be changed sometimes.
Learn Slices
DEV Community
Posted on Sep 6, 2020 • Originally published at Medium
11 Solutions of Exercises in GoLang Tour
The Tour of Go Website is an excellent start for an developer trying to learn the language Go. It gradually introduces you to the language by explaining different parts and provides exercises to the reader to implement.
Following are the solutions I wrote for the exercises as I went through the tour.
Exercise 1. Loops and Functions
Given a number x, we want to find the number z for which z² is most nearly x.
Exercise 2. Slices
Implement Pic. It should return a slice of length dy, each element of which is a slice of dx 8-bit unsigned integers.
Exercise 3. Maps
Implement WordCount. It should return a map of the counts of each "word" in the string s. The wc. Test function runs a test suite against the provided function and prints success or failure.
Exercise 4. Fibonacci Closure
Implement a fibonacci function that returns a function (a closure) that returns successive fibonacci numbers (0, 1, 1, 2, 3, 5, …)
Exercise 5. Stringers
IPAddr type implement fmt.Stringer to print the address as a dotted quad.
Exercise 6. Errors
Sqrt should return a non-nil error value when given a negative number, as it doesn't support complex numbers.
Exercise 7. Readers
Implement a Reader type that emits an infinite stream of the ASCII character 'A'.
Exercise 8. rot13Reader
Implement a rot13Reader that implements io.Reader and reads from an io.Reader, modifying the stream by applying the rot13 substitution cipher to all alphabetical characters
Exercise 9: Images
Write another one, but this time it will return an implementation of image.Image instead of a slice of data. Define your own Image type, implement the necessary methods, and call pic.ShowImage. Bounds should return a image.Rectangle, like image.Rect(0, 0, w, h). ColorModel should return color.RGBAModel. At should return a color; the value v in the last picture generator corresponds to color.RGBA{v, v, 255, 255} in this one.
Exercise 10: Equivalent Binary Trees
Implement the Walk function and Same function using Walk to determine whether t1 and t2 store the same values.
Exercise 11: Web Crawler
Use Go's concurrency features to parallelize a web crawler.Modify the Crawl function to fetch URLs in parallel without fetching the same URL twice.
Follow NMTechBytes on Twitter for my daily tech bites :)
Special Thanks …
- weppos/44.go
- Image Source
Top comments (2)
Templates let you quickly answer FAQs or store snippets for re-use.
- Location London, U.K.
- Work Senior Software Engineer at WhatsApp
- Joined Mar 16, 2020
I think the solution for exercise 10 may be incorrect.
Expected output: false
Actual output: true
Change suggestion:
Adding these lines above return true seems to fix the problem:
- Joined Sep 23, 2021
exercise 11 Just lock cache set or get is not good enough. You will need atomic read–modify–write so that no other thread can read between current thread cache get and set.
Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .
Hide child comments as well
For further actions, you may consider blocking this person and/or reporting abuse
An In-depth Insights on the Business Ventures of Adtech Visionary Evan Rutchik
Editor world - Mar 26
Key Insights on Maximizing Shopify Store Profits
Skyla - Mar 26
BAML: A new programming language for using LLMs + a VSCode Playground
hellovai - Mar 26
Control HTTP Requests in .NET: Methods, Response Handling and Use of External Libraries
Adrián Bailador - Mar 26
We're a place where coders share, stay up-to-date and grow their careers.
Cloud-oriented Life
Cloud Native Technology Improves Lives
[Golang (Go) Tutorial] Slices
[1] Go Slices: usage and internals - The Go Blog - https://blog.golang.org/slices-intro
[3] Slice | A Tour of Go - https://tour.golang.org/moretypes/7
[2] Go by Example: Slices - https://gobyexample.com/slices
[1] The anatomy of Slices in Go. Slices are like Arrays but they can… | by Uday Hiwarale | RunGo | Medium - https://medium.com/rungo/the-anatomy-of-slices-in-go-6450e3bb2b94
[] Go - Slices - Tutorialspoint - https://www.tutorialspoint.com/go/go_slice.htm
[] Slices in Golang - GeeksforGeeks - https://www.geeksforgeeks.org/slices-in-golang/
[] Go slice - working with slices in Golang - https://zetcode.com/golang/slice/
[] Learning Go — Array, Slice, Map. In this article, we are going to see… | by Madhavan Nagarajan | Level Up Coding - https://levelup.gitconnected.com/learning-go-array-slice-map-934eed320b1c
SliceTricks · golang/go Wiki - https://github.com/golang/go/wiki/SliceTricks
[] Golang Slices Tutorial with examples - golangprograms.com - https://www.golangprograms.com/go-language/slices-in-golang-programming.html
[] Slices/arrays explained: create, index, slice, iterate · YourBasic Go - https://yourbasic.org/golang/slices-explained/
IMAGES
VIDEO
COMMENTS
In practice, slices are much more common than arrays. The type []T is a slice with elements of type T . A slice is formed by specifying two indices, a low and high bound, separated by a colon: a[low : high] This selects a half-open range which includes the first element, but excludes the last one. The following expression creates a slice which ...
Tour of Go exercise #18: Slices. I am trying to complete the Exercise: Slices from the Go Tour. However I don't really understand what I'm being asked to do. Implement Pic. It should return a slice of length dy, each element of which is a slice of dx 8-bit unsigned integers. When you run the program, it will display your picture, interpreting ...
Slice length and capacity. A slice has both a length and a capacity . The length of a slice is the number of elements it contains. The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice. The length and capacity of a slice s can be obtained using the expressions len (s) and cap (s) .
Creating a slice with make. Slices can be created with the built-in make function; this is how you create dynamically-sized arrays. The make function allocates a zeroed array and returns a slice that refers to that array: a := make([]int, 5) // len(a)=5. To specify a capacity, pass a third argument to make:
Watch me solve the slices exercise in a tour of go. Be aware that I just recently started learning Go, so don't take this a s THE way to solve this exercise....
Here we create an empty slice c of the same length as s and copy into c from s. c:= make ([] string, len (s)) copy (c, s) fmt. Println ("cpy:", c) Slices support a "slice" operator with the syntax slice[low:high]. For example, this gets a slice of the elements s[2], s[3], and s[4]. l:= s [2: 5] fmt. Println ("sl1:", l) This slices up to ...
The slice type is an abstraction built on top of Go's array type, and so to understand slices we must first understand arrays. An array type definition specifies a length and an element type. For example, the type [4]int represents an array of four integers. An array's size is fixed; its length is part of its type ( [4]int and [5]int are ...
An answer of the exercise: Slices on a tour of Go. GitHub Gist: instantly share code, notes, and snippets.
Go empowers developers with a fantastic set of built-in tools. These tools help you write, build, test, and manage your projects with ease… 11 min read · 6 days ago
Slices in Go are based on arrays. Arrays have a fixed size. A slice, on the other hand, is a dynamically-sized, flexible view of the elements of an array. A slice is written like []T with T being the type of the elements in the slice: var empty []int // an empty slice. withData := []int{0,1,2,3,4,5} // a slice pre-filled with some data.
The Tour of Go Website is an excellent start for an developer trying to learn the language Go. ... but this time it will return an implementation of image.Image instead of a slice of data. Define ...
Exercise 2. Slices. Implement Pic. It should return a slice of length dy, each element of which is a slice of dx 8-bit unsigned integers. Exercise 3. Maps. Implement WordCount. It should return a map of the counts of each "word" in the string s. The wc.
Throughout the tour you will find a series of slides and exercises for you to complete. You can navigate through them using "previous" or PageUp to go to the previous page, "next" or PageDown to go to the next page. The tour is interactive. Click the Run button now (or press Shift + Enter) to compile and run the program on a remote server. The ...
Posted on 2020-02-01 Edited on 2023-09-02 In Programming Language, Golang (Go), Golang (Go) Tutorial Views: Word count in article: 1k Reading time ≈ 1 mins. Slices References
Slices are like references to arrays. A slice does not store any data, it just describes a section of an underlying array. Changing the elements of a slice modifies the corresponding elements of its underlying array. Other slices that share the same underlying array will see those changes. < 8/27 >. slices-pointers.go Syntax Imports. 22. 1.
In Go, a name is exported if it begins with a capital letter. For example, Pizza is an exported name, as is Pi, which is exported from the math package. pizza and pi do not start with a capital letter, so they are not exported. When importing a package, you can refer only to its exported names. Any "unexported" names are not accessible from ...
The Go Programming Language Specification. Slice types. Slice expressions. For a string, array, pointer to array, or slice a, the primary expression. a[low : high] constructs a substring or slice. The indices low and high select which elements of operand a appear in the result. The result has indices starting at 0 and length equal to high - low.
A Tour of Go. A Tour of Go. Using the tour. Welcome! Hello, 世界 ... The example code sums the numbers in a slice, distributing the work between two goroutines. Once both goroutines have completed their computation, it calculates the final result. < 2/11 > channels.go Syntax Imports. 23 . 1.
How can the slice be called as dynamically sized when it cannot go beyond the size of the underlying array. The types are static vs dynamic. An array type is like [4]byte - the size is part of the type definition, and therefore set at compile time. Only a [4]byte can be stored in a variable of type [4]byte.Not a [3]byte, not a [5]byte.It's static.
Appending to a slice. It is common to append new elements to a slice, and so Go provides a built-in append function. The documentation of the built-in package describes append.. func append(s []T, vs ...T) []T. The first parameter s of append is a slice of type T, and the rest are T values to append to the slice.. The resulting value of append is a slice containing all the elements of the ...