<small>Discover Insane Possibility
of Go Slice Usage
from Runtime Source Code</small>
===
<!-- .slide: data-background-color="pink" -->
<!-- .slide: data-transition="zoom" -->
> [name=郭學聰 Hsueh-Tsung Kuo]
> [time=Sat, 31 Jul 2021] [color=red]
###### CC BY-SA 4.0
---
<!-- .slide: data-transition="convex" -->
## Who am I?
![fieliapm](https://www.gravatar.com/avatar/2aef78f04240a6ac9ccd473ba1cbd1e3?size=2048 =384x384)
<small>Someone (who?) said:
a game programmer should be able to draw cute anime character(?)</small>
----
<!-- .slide: data-transition="convex" -->
* A programmer from game company in Taiwan
* Backend (and temporary frontend) engineer
* Usually develop something related to my work in Python, Ruby, ECMAScript, Golang, C#
* ECMAScript hater since **Netscape** is dead
* Built CDN-aware game asset update system
* Professional small vehicle driver
* Draw cute anime character in spare time
---
<!-- .slide: data-transition="convex" -->
## Outline
----
<!-- .slide: data-transition="convex" -->
4. What is Slice?
* Array
* Slice
----
<!-- .slide: data-transition="convex" -->
5. Source Code of Slice Implementation
* Runtime
* Slice Structure
* Caution
* Utility Functions
* Where is append()?
* Compile Time
* Slice Operation
* Accessing Slice Elements
* Re-slicing
* Machine Code Optimization
----
<!-- .slide: data-transition="convex" -->
6. Insane Slice Application
* SliceTricks
* Application in Algorithm
* One More Thing
7. Conclusion
8. Resource
9. Q&A
---
<!-- .slide: data-transition="convex" -->
## What is Slice?
----
<!-- .slide: data-transition="convex" -->
### Array
```go=
var a [4]int
a[0] = 1
i := a[0]
// i == 1
// a[2] == 0, the zero value of the int type
```
----
<!-- .slide: data-transition="convex" -->
#### Array Structure
![array](https://blog.golang.org/slices-intro/slice-array.png)
----
<!-- .slide: data-transition="convex" -->
#### Array Literal
```go=
b := [2]string{"Penn", "Teller"}
// make the compiler count the array elements
b := [...]string{"Penn", "Teller"}
```
----
<!-- .slide: data-transition="convex" -->
### Slice
```go=
func make([]T, len, cap) []T
var s []byte
s = make([]byte, 5, 5)
// s == []byte{0, 0, 0, 0, 0}
```
----
<!-- .slide: data-transition="convex" -->
### Slice
```go=
s := make([]byte, 5)
len(s) == 5
cap(s) == 5
```
----
<!-- .slide: data-transition="convex" -->
#### Slice Structure
![slice_struct](https://blog.golang.org/slices-intro/slice-struct.png)
![slice_struct](https://blog.golang.org/slices-intro/slice-1.png)
----
<!-- .slide: data-transition="convex" -->
#### Slice Literal
```go=
letters := []string{"a", "b", "c", "d"}
```
---
<!-- .slide: data-transition="convex" -->
## Source Code of Slice Implementation
----
<!-- .slide: data-transition="convex" -->
### Runtime
<small>https://github.com/golang/go/blob/go1.16.5/src/runtime/slice.go</small>
----
<!-- .slide: data-transition="convex" -->
#### Slice Structure
```go=
type slice struct {
array unsafe.Pointer
len int
cap int
}
```
----
<!-- .slide: data-transition="convex" -->
##### Caution
* Underlying arrays of slices are mutable
* Slices themselves are immutable
* Call by value
----
<!-- .slide: data-transition="convex" -->
#### Utility Functions
```go=
func makeslice(et *_type, len, cap int) unsafe.Pointer
func growslice(et *_type, old slice, cap int) slice
func slicecopy(toPtr unsafe.Pointer, toLen int, fromPtr unsafe.Pointer, fromLen int, width uintptr)
append() // where?
```
----
<!-- .slide: data-transition="convex" -->
#### Where is append()?
<small>https://github.com/golang/go/blob/go1.16.5/src/cmd/compile/internal/gc/ssa.go#L2841</small>
----
<!-- .slide: data-transition="convex" -->
### Compile Time
<small>https://github.com/golang/go/blob/go1.16.5/src/cmd/compile/internal/gc/ssa.go#L5458</small>
----
<!-- .slide: data-transition="convex" -->
#### Slice Operation
* Accessing slice elements
* Re-slicing
----
<!-- .slide: data-transition="convex" -->
##### Accessing Slice Elements
* slice
* string
* pointer
```go=
val := s[2]
s[3] = val
```
----
<!-- .slide: data-transition="convex" -->
##### Re-slicing
* slice
* string
* pointer
```go=
// i : begin index (include)
// j : end index (exclude)
// k : index of capacity boundary (exclude)
s := v[i:j:k]
```
----
<!-- .slide: data-transition="convex" -->
###### Boundary Checking
```go=
// k <= cap(v)
// j <= k
s := v[i:j:k]
```
* :heavy_check_mark: "len(s) > len(v)" <!-- .element: class="fragment" data-fragment-index="1" -->
* if capacity of underlying array is enough <!-- .element: class="fragment" data-fragment-index="2" -->
* :x: **string** doesn't have cap property <!-- .element: class="fragment" data-fragment-index="3" -->
----
<!-- .slide: data-transition="convex" -->
###### New Slice Caculation
```go=
// Calculate the base pointer (rptr) for the new slice.
//
// Generate the following code assuming that indexes are in bounds.
// The masking is to make sure that we don't generate a slice
// that points to the next object in memory. We cannot just set
// the pointer to nil because then we would create a nil slice or
// string.
//
// rcap = k - i
// rlen = j - i
// rptr = ptr + (mask(rcap) & (i * stride))
//
// Where mask(x) is 0 if x==0 and -1 if x>0 and stride is the width
// of the element type.
```
----
<!-- .slide: data-transition="convex" -->
#### Machine Code Optimization
* Re-slicing
* Not atomic
* Instruction might be interleaved in optimized assembly code
* Discard boundary checking operation
* If compiler detects that overflow will not happen <!-- .element: class="fragment" data-fragment-index="1" -->
---
<!-- .slide: data-transition="convex" -->
## Insane Slice Application
----
<!-- .slide: data-transition="convex" -->
### SliceTricks
* Official
* <small>https://github.com/golang/go/wiki/SliceTricks</small>
* Graphics by @ueokande
* <small>https://ueokande.github.io/go-slice-tricks/</small>
----
<!-- .slide: data-transition="convex" -->
#### AppendVector
![AppendVector1](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/AppendVector1.svg)
![AppendVector2](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/AppendVector2.svg)
```go=
a = append(a, b...)
```
----
<!-- .slide: data-transition="convex" -->
#### Copy
![Copy](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Copy.svg)
```go=
b = make([]T, len(a))
copy(b, a)
```
```go=
b = append([]T(nil), a...)
```
```go=
b = append(a[:0:0], a...)
```
----
<!-- .slide: data-transition="convex" -->
#### Cut
![Cut](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Cut.svg)
```go=
a = append(a[:i], a[j:]...)
```
----
<!-- .slide: data-transition="convex" -->
#### Delete
![Delete1](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Delete1.svg)
```go=
a = append(a[:i], a[i+1:]...)
```
```go=
a = a[:i+copy(a[i:], a[i+1:])]
```
----
<!-- .slide: data-transition="convex" -->
#### Delete without preserving order
![DeleteWithoutPreservingOrder](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/DeleteWithoutPreservingOrder.svg)
```go=
a[i] = a[len(a)-1]
a = a[:len(a)-1]
```
----
<!-- .slide: data-transition="convex" -->
#### Cut (GC)
![CutGC](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/CutGC.svg)
```go=
copy(a[i:], a[j:])
for k, n := len(a)-j+i, len(a); k < n; k++ {
a[k] = nil // or the zero value of T
}
a = a[:len(a)-j+i]
```
----
<!-- .slide: data-transition="convex" -->
#### Delete (GC)
![DeleteGC](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/DeleteGC.svg)
```go=
copy(a[i:], a[i+1:])
a[len(a)-1] = nil // or the zero value of T
a = a[:len(a)-1]
```
----
<!-- .slide: data-transition="convex" -->
#### Delete without preserving order (GC)
![DeleteWithoutPreservingOrderGC](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/DeleteWithoutPreservingOrderGC.svg)
```go=
a[i] = a[len(a)-1]
a[len(a)-1] = nil
a = a[:len(a)-1]
```
----
<!-- .slide: data-transition="convex" -->
#### Expand
![Expand](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Expand.svg)
```go=
a = append(a[:i], append(make([]T, j), a[i:]...)...)
```
----
<!-- .slide: data-transition="convex" -->
#### Extend
![Extend](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Extend.svg)
```go=
a = append(a, make([]T, j)...)
```
----
<!-- .slide: data-transition="convex" -->
#### Filter (in place)
![Filter](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Filter.svg)
```go=
n := 0
for _, x := range a {
if keep(x) {
a[n] = x
n++
}
}
a = a[:n]
```
----
<!-- .slide: data-transition="convex" -->
#### Insert
![Insert](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Insert.svg)
```go=
a = append(a[:i], append([]T{x}, a[i:]...)...)
```
----
<!-- .slide: data-transition="convex" -->
#### InsertVector
![InsertVector](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/InsertVector.svg)
```go=
a = append(a[:i], append(b, a[i:]...)...)
```
----
<!-- .slide: data-transition="convex" -->
#### Push
![Push](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Push.svg)
```go=
a = append(a, x)
```
----
<!-- .slide: data-transition="convex" -->
#### Pop
![Extend](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Pop.svg)
```go=
x, a = a[len(a)-1], a[:len(a)-1]
```
----
<!-- .slide: data-transition="convex" -->
#### Push Front/Unshift
![Unshift](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Unshift.svg)
```go=
a = append([]T{x}, a...)
```
----
<!-- .slide: data-transition="convex" -->
#### Pop Front/Shift
![Shift](https://raw.githubusercontent.com/ueokande/go-slice-tricks/master/src/components/CheatSheet/Shift.svg)
```go=
x, a = a[0], a[1:]
```
----
<!-- .slide: data-transition="convex" -->
### Application in Algorithm
----
<!-- .slide: data-transition="convex" -->
#### QuickSort
```go=
func QuickSort(a []int) {
if len(a) <= 1 {
return
}
pivot := rand.Int() % len(a)
left, right := 0, len(a)-1
a[pivot], a[right] = a[right], a[pivot]
for i, _ := range a[:right] {
if a[i] < a[right] {
a[left], a[i] = a[i], a[left]
left++
}
}
a[left], a[right] = a[right], a[left]
QuickSort(a[:left])
QuickSort(a[left+1:])
}
```
----
<!-- .slide: data-transition="convex" -->
### One More Thing
----
<!-- .slide: data-transition="convex" -->
#### Slice Capacity :heavy_plus_sign: append()
```go=
s := []int{1, 2, 3, 4, 5, 6, 7, 8}
fmt.Printf("s == %v\n\n", s)
s2 := s[1:4:5]
fmt.Printf("s2 == %v\n\n", s2)
s2 = append(s2, 15)
fmt.Printf("s == %v\n", s)
fmt.Printf("s2 == %v\n\n", s2)
s3 := s2[:4:4]
fmt.Printf("s3 == %v\n\n", s3)
s2 = append(s2, 16)
fmt.Printf("s == %v\n", s)
fmt.Printf("s2 == %v\n\n", s2)
```
----
<!-- .slide: data-transition="convex" -->
#### Result
```go
s == [1 2 3 4 5 6 7 8]
s2 == [2 3 4]
s == [1 2 3 4 15 6 7 8]
s2 == [2 3 4 15]
s3 == [2 3 4 15]
s == [1 2 3 4 15 6 7 8]
s2 == [2 3 4 15 16]
```
---
<!-- .slide: data-transition="convex" -->
## Conclusion
----
<!-- .slide: data-transition="convex" -->
### Slice is Invincible
* Accessing slice elements
* Re-slicing
* append()
----
<!-- .slide: data-transition="convex" -->
### Bless
:hash: {成為 slice 大師|<big>Become slice master</big>}
> [name=郭學聰 Hsueh-Tsung Kuo] [time=2021_07_31] [color=red] :notebook:
---
<!-- .slide: data-transition="convex" -->
## Resource
----
<!-- .slide: data-transition="convex" -->
### Reference
* Slice introduction
* <small>https://blog.golang.org/slices-intro</small>
* Slice source code
* <small>https://github.com/golang/go/blob/go1.16.5/src/runtime/slice.go</small>
* <small>https://github.com/golang/go/blob/go1.16.5/src/cmd/compile/internal/gc/ssa.go</small>
* SliceTricks
* Official
* <small>https://github.com/golang/go/wiki/SliceTricks</small>
* Graphics by @ueokande
* <small>https://ueokande.github.io/go-slice-tricks/</small>
----
<!-- .slide: data-transition="convex" -->
### Utility
* Slides
* Editor: HackMD
* Presentation: Mozilla FireFox
* Recording
* OBS Studio
* Panasonic DC-GH5
* LEICA DG SUMMILUX 15mm/F1.7
* Video Editing & Compositing
* AviSynth official builds
---
<!-- .slide: data-transition="zoom" -->
## Q&A
---
<style>
.reveal {
background: #FFDFEF;
color: black;
}
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
color: black;
}
.reveal code {
font-size: 18px !important;
line-height: 1.2;
}
.progress div{
height:14px !important;
background: hotpink !important;
}
// original template
.rightpart{
float:right;
width:50%;
}
.leftpart{
margin-right: 50% !important;
height:50%;
}
.reveal section img { background:none; border:none; box-shadow:none; }
p.blo {
font-size: 50px !important;
background:#B6BDBB;
border:1px solid silver;
display:inline-block;
padding:0.5em 0.75em;
border-radius: 10px;
box-shadow: 5px 5px 5px #666;
}
p.blo1 {
background: #c7c2bb;
}
p.blo2 {
background: #b8c0c8;
}
p.blo3 {
background: #c7cedd;
}
p.bloT {
font-size: 60px !important;
background:#B6BDD3;
border:1px solid silver;
display:inline-block;
padding:0.5em 0.75em;
border-radius: 8px;
box-shadow: 1px 2px 5px #333;
}
p.bloA {
background: #B6BDE3;
}
p.bloB {
background: #E3BDB3;
}
/*.slide-number{
margin-bottom:10px !important;
width:100%;
text-align:center;
font-size:25px !important;
background-color:transparent !important;
}*/
iframe.myclass{
width:100px;
height:100px;
bottom:0;
left:0;
position:fixed;
border:none;
z-index:99999;
}
h1.raw {
color: #fff;
background-image: linear-gradient(90deg,#f35626,#feab3a);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: hue 5s infinite linear;
}
@keyframes hue {
from {
filter: hue-rotate(0deg);
}
to {
filter: hue-rotate(360deg);
}
}
.progress{
height:14px !important;
}
.progress span{
height:14px !important;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAMCAIAAAAs6UAAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUNCQzIyREQ0QjdEMTFFMzlEMDM4Qzc3MEY0NzdGMDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUNCQzIyREU0QjdEMTFFMzlEMDM4Qzc3MEY0NzdGMDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQ0JDMjJEQjRCN0QxMUUzOUQwMzhDNzcwRjQ3N0YwOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQ0JDMjJEQzRCN0QxMUUzOUQwMzhDNzcwRjQ3N0YwOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PovDFgYAAAAmSURBVHjaYvjPwMAAxjMZmBhA9H8INv4P4TPM/A+m04zBNECAAQBCWQv9SUQpVgAAAABJRU5ErkJggg==") repeat-x !important;
}
.progress span:after,
.progress span.nyancat{
content: "";
background: url('data:image/gif;base64,R0lGODlhIgAVAKIHAL3/9/+Zmf8zmf/MmZmZmf+Z/wAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpDMkJBNjY5RTU1NEJFMzExOUM4QUM2MDAwNDQzRERBQyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCREIzOEIzMzRCN0IxMUUzODhEQjgwOTYzMTgyNTE0QiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCREIzOEIzMjRCN0IxMUUzODhEQjgwOTYzMTgyNTE0QiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkM1QkE2NjlFNTU0QkUzMTE5QzhBQzYwMDA0NDNEREFDIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMyQkE2NjlFNTU0QkUzMTE5QzhBQzYwMDA0NDNEREFDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkECQcABwAsAAAAACIAFQAAA6J4umv+MDpG6zEj682zsRaWFWRpltoHMuJZCCRseis7xG5eDGp93bqCA7f7TFaYoIFAMMwczB5EkTzJllEUttmIGoG5bfPBjDawD7CsJC67uWcv2CRov929C/q2ZpcBbYBmLGk6W1BRY4MUDnMvJEsBAXdlknk2fCeRk2iJliAijpBlEmigjR0plKSgpKWvEUheF4tUZqZID1RHjEe8PsDBBwkAIfkECQcABwAsAAAAACIAFQAAA6B4umv+MDpG6zEj682zsRaWFWRpltoHMuJZCCRseis7xG5eDGp93TqS40XiKSYgTLBgIBAMqE/zmQSaZEzns+jQ9pC/5dQJ0VIv5KMVWxqb36opxHrNvu9ptPfGbmsBbgSAeRdydCdjXWRPchQPh1hNAQF4TpM9NnwukpRyi5chGjqJEoSOIh0plaYsZBKvsCuNjY5ptElgDyFIuj6+vwcJACH5BAkHAAcALAAAAAAiABUAAAOfeLrc/vCZSaudUY7Nu99GxhhcYZ7oyYXiQQ5pIZgzCrYuLMd8MbAiUu802flYGIhwaCAQDKpQ86nUoWqF6dP00wIby572SXE6vyMrlmhuu9GKifWaddvNQAtszXYCxgR/Zy5jYTFeXmSDiIZGdQEBd06QSBQ5e4cEkE9nnZQaG2J4F4MSLx8rkqUSZBeurhlTUqsLsi60DpZxSWBJugcJACH5BAkHAAcALAAAAAAiABUAAAOgeLrc/vCZSaudUY7Nu99GxhhcYZ7oyYXiQQ5pIZgzCrYuLMd8MbAiUu802flYGIhwaCAQDKpQ86nUoWqF6dP00wIby572SXE6vyMrlmhuu9GuifWaddvNwMkZtmY7AWMEgGcKY2ExXl5khFMVc0Z1AQF3TpJShDl8iASST2efloV5JTyJFpgOch8dgW9KZxexshGNLqgLtbW0SXFwvaJfCQAh+QQJBwAHACwAAAAAIgAVAAADoXi63P7wmUmrnVGOzbvfRsYYXGGe6MmF4kEOaSGYMwq2LizHfDGwIlLPNKGZfi6gZmggEAy2iVPZEKZqzakq+1xUFFYe90lxTsHmim6HGpvf3eR7skYJ3PC5tyystc0AboFnVXQ9XFJTZIQOYUYFTQEBeWaSVF4bbCeRk1meBJYSL3WbaReMIxQfHXh6jaYXsbEQni6oaF21ERR7l0ksvA0JACH5BAkHAAcALAAAAAAiABUAAAOeeLrc/vCZSaudUY7Nu99GxhhcYZ7oyYXiQQ5pIZgzCrYuLMfFlA4hTITEMxkIBMOuADwmhzqeM6mashTCXKw2TVKQyKuTRSx2wegnNkyJ1ozpOFiMLqcEU8BZHx6NYW8nVlZefQ1tZgQBAXJIi1eHUTRwi0lhl48QL0sogxaGDhMlUo2gh14fHhcVmnOrrxNqrU9joX21Q0IUElm7DQkAIfkECQcABwAsAAAAACIAFQAAA6J4umv+MDpG6zEj682zsRaWFWRpltoHMuJZCCRseis7xG5eDGp93bqCA7f7TFaYoIFAMMwczB5EkTzJllEUttmIGoG5bfPBjDawD7CsJC67uWcv2CRov929C/q2ZpcBbYBmLGk6W1BRY4MUDnMvJEsBAXdlknk2fCeRk2iJliAijpBlEmigjR0plKSgpKWvEUheF4tUZqZID1RHjEe8PsDBBwkAIfkECQcABwAsAAAAACIAFQAAA6B4umv+MDpG6zEj682zsRaWFWRpltoHMuJZCCRseis7xG5eDGp93TqS40XiKSYgTLBgIBAMqE/zmQSaZEzns+jQ9pC/5dQJ0VIv5KMVWxqb36opxHrNvu9ptPfGbmsBbgSAeRdydCdjXWRPchQPh1hNAQF4TpM9NnwukpRyi5chGjqJEoSOIh0plaYsZBKvsCuNjY5ptElgDyFIuj6+vwcJACH5BAkHAAcALAAAAAAiABUAAAOfeLrc/vCZSaudUY7Nu99GxhhcYZ7oyYXiQQ5pIZgzCrYuLMd8MbAiUu802flYGIhwaCAQDKpQ86nUoWqF6dP00wIby572SXE6vyMrlmhuu9GKifWaddvNQAtszXYCxgR/Zy5jYTFeXmSDiIZGdQEBd06QSBQ5e4cEkE9nnZQaG2J4F4MSLx8rkqUSZBeurhlTUqsLsi60DpZxSWBJugcJACH5BAkHAAcALAAAAAAiABUAAAOgeLrc/vCZSaudUY7Nu99GxhhcYZ7oyYXiQQ5pIZgzCrYuLMd8MbAiUu802flYGIhwaCAQDKpQ86nUoWqF6dP00wIby572SXE6vyMrlmhuu9GuifWaddvNwMkZtmY7AWMEgGcKY2ExXl5khFMVc0Z1AQF3TpJShDl8iASST2efloV5JTyJFpgOch8dgW9KZxexshGNLqgLtbW0SXFwvaJfCQAh+QQJBwAHACwAAAAAIgAVAAADoXi63P7wmUmrnVGOzbvfRsYYXGGe6MmF4kEOaSGYMwq2LizHfDGwIlLPNKGZfi6gZmggEAy2iVPZEKZqzakq+1xUFFYe90lxTsHmim6HGpvf3eR7skYJ3PC5tyystc0AboFnVXQ9XFJTZIQOYUYFTQEBeWaSVF4bbCeRk1meBJYSL3WbaReMIxQfHXh6jaYXsbEQni6oaF21ERR7l0ksvA0JACH5BAkHAAcALAAAAAAiABUAAAOeeLrc/vCZSaudUY7Nu99GxhhcYZ7oyYXiQQ5pIZgzCrYuLMfFlA4hTITEMxkIBMOuADwmhzqeM6mashTCXKw2TVKQyKuTRSx2wegnNkyJ1ozpOFiMLqcEU8BZHx6NYW8nVlZefQ1tZgQBAXJIi1eHUTRwi0lhl48QL0sogxaGDhMlUo2gh14fHhcVmnOrrxNqrU9joX21Q0IUElm7DQkAOw==') !important;
width: 34px !important;
height: 21px !important;
border: none !important;
float:right;
margin-top:-7px;
margin-right:-10px;
}
</style>
{"metaMigratedAt":"2023-06-16T03:50:13.586Z","metaMigratedFrom":"YAML","title":"Discover Insane Possibility of Go Slice Usage from Runtime Source Code","breaks":true,"description":"View the slide with \"Slide Mode\".","slideOptions":"{\"spotlight\":{\"enabled\":false},\"allottedMinutes\":25}","contributors":"[{\"id\":\"ea27dcd7-a3f2-47c2-b25e-6760e7936c38\",\"add\":57676,\"del\":36697}]"}