Skip to content

Commit 8ab8b9d

Browse files
committed
...
1 parent 31c6092 commit 8ab8b9d

File tree

3 files changed

+205
-31
lines changed

3 files changed

+205
-31
lines changed

misc/content/2022/06/hands-on-array-in-golang/hands-on-array-in-golang.ipynb

Lines changed: 179 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@
3030
" in the sense that the length of an array is part of its type\n",
3131
" and must be determined at compile time.\n",
3232
" \n",
33-
"2. Array is a primitive (value) type in Golang.\n",
34-
" When assigned to another variable \n",
35-
" or passed as a parameter,\n",
33+
"2. When an array is assigned to another variable \n",
34+
" or passed to a function as a parameter,\n",
3635
" it is copied!\n",
3736
" For this reason, \n",
3837
" array is not a good interface to use.\n",
@@ -480,7 +479,39 @@
480479
"source": [
481480
"## [Slice](https://go.dev/ref/spec#Slice_types)\n",
482481
"\n",
483-
"Slice in Golang is similar to `Vec` in Rust."
482+
"A Slice in Golang is similar to a dynamic array (or vector) in other programming languages.\n",
483+
"However,\n",
484+
"due to Golang's unique design (lacking of class),\n",
485+
"a Slice behaves different and sometimes confusing to users coming from other programming languages.\n",
486+
"A Slice in Golang is implemented as a descriptor (struct) containing a data pointer, a length and a capacity. \n",
487+
"Due to this design,\n",
488+
"1. When you pass a Slice (value copy) to a function in Golang,\n",
489+
" the function can update existing values in the Slice\n",
490+
" (as the copied Slice in the function shares the same underlying data pointer as the original Slice).\n",
491+
"2. The built-in function `append` can be used to append values into a slice.\n",
492+
" Since `append` takes a Slice (instead of a pointer to a Slice) by value,\n",
493+
" it cannot update the original Slice descriptor (struct),\n",
494+
" so it has to return a new Slice descriptor.\n",
495+
" This sounds like append isn't appending in place\n",
496+
" which is a misunderstanding.\n",
497+
" - When there's no capacity left in the underlying array,\n",
498+
" append has to allocate a new chunk of memory and copies value over.\n",
499+
" Appending isn't in place in this case,\n",
500+
" but it's true in any programming language.\n",
501+
" - When there's capacity left in the udnerlying array,\n",
502+
" appending happens in place in the underlying array\n",
503+
" (as no new memory allocation is required).\n",
504+
" However,\n",
505+
" since a new slice descriptor is returned by `append`\n",
506+
" and the origial slice descriptor stays the same,\n",
507+
" the original slice descriptor is still a view of the old array window\n",
508+
" instead of the new updated array window.\n",
509+
" - Sometimes,\n",
510+
" you want to pass a slice to another function for appending values\n",
511+
" and want the change to be reflected outside the function.\n",
512+
" To achieve this,\n",
513+
" you can pass a pointor to the Slice descriptor.\n",
514+
" "
484515
]
485516
},
486517
{
@@ -666,7 +697,9 @@
666697
"source": [
667698
"## Appending to a Slice\n",
668699
"\n",
669-
"[Appending to a slice](https://go.dev/tour/moretypes/15)"
700+
"[Appending to a slice](https://go.dev/tour/moretypes/15)\n",
701+
"\n",
702+
"1. Appending to "
670703
]
671704
},
672705
{
@@ -815,18 +848,85 @@
815848
},
816849
{
817850
"cell_type": "code",
818-
"execution_count": 47,
851+
"execution_count": 1,
819852
"metadata": {},
820853
"outputs": [
821854
{
822855
"data": {
823-
"text/plain": [
824-
"[78 89 45 56 14]"
856+
"text/html": [
857+
"\n",
858+
"<style>\n",
859+
".gonb-err-location {\n",
860+
"\tbackground: var(--jp-err-color2); \n",
861+
"\tborder-radius: 3px;\n",
862+
"\tborder-style: dotted;\n",
863+
"\tborder-width: 1px;\n",
864+
"\tborder-color: var(--jp-border-color2);\n",
865+
"}\n",
866+
".gonb-err-location:hover {\n",
867+
"\tborder-width: 2px;\n",
868+
"\tborder-style: solid;\n",
869+
"\tborder-color: var(--jp-border-color2);\n",
870+
"}\n",
871+
".gonb-err-context {\n",
872+
"\tdisplay: none;\n",
873+
"}\n",
874+
".gonb-err-location:hover + .gonb-err-context {\n",
875+
"\tbackground: var(--jp-dialog-background); \n",
876+
"\tborder-radius: 3px;\n",
877+
"\tborder-style: solid;\n",
878+
"\tborder-width: 1px;\n",
879+
"\tborder-color: var(--jp-border-color2);\n",
880+
"\tdisplay: block;\n",
881+
"\twhite-space: pre;\n",
882+
"\tfont-family: monospace;\n",
883+
"}\n",
884+
".gonb-err-line {\n",
885+
"\tborder-radius: 3px;\n",
886+
"\tborder-style: dotted;\n",
887+
"\tborder-width: 1px;\t\n",
888+
"\tborder-color: var(--jp-border-color2);\n",
889+
"\tbackground-color: var(--jp-rendermime-err-background);\n",
890+
"\tfont-weight: bold;\n",
891+
"}\n",
892+
".gonb-cell-line-info {\n",
893+
"\tbackground: var(--jp-layout-color2);\n",
894+
"\tcolor: #999;\n",
895+
"\tmargin: 0.1em;\n",
896+
"\tborder: 1px solid var(--jp-border-color1);\n",
897+
"\tpadding-left: 0.2em;\n",
898+
"\tpadding-right: 0.2em;\n",
899+
"}\n",
900+
"</style>\n",
901+
"<div class=\"lm-Widget p-Widget lm-Panel p-Panel jp-OutputArea-child\">\n",
902+
"<div class=\"lm-Widget p-Widget jp-RenderedText jp-mod-trusted jp-OutputArea-output\" data-mime-type=\"application/vnd.jupyter.stderr\" style=\"font-family: monospace;\">\n",
903+
"\n",
904+
"<span class=\"gonb-cell-line-info\">Cell[1]: Line 1</span>\n",
905+
"<span class=\"gonb-err-location\">/tmp/gonb_e532465a/main.go:3:1: </span> expected declaration, found vec\n",
906+
"<div class=\"gonb-err-context\">\n",
907+
"package main\n",
908+
"\n",
909+
"<div class=\"gonb-err-line\">vec := []int{78, 89, 45, 56, 14}\n",
910+
"</div>vec\n",
911+
"\n",
912+
"\n",
913+
"</div>\n",
914+
"\n",
915+
"<br/>\n",
916+
"\n",
917+
"</div>\n"
825918
]
826919
},
827-
"execution_count": 47,
828920
"metadata": {},
829-
"output_type": "execute_result"
921+
"output_type": "display_data"
922+
},
923+
{
924+
"ename": "ERROR",
925+
"evalue": "parsing go files in TempDir \"/tmp/gonb_e532465a\": /tmp/gonb_e532465a/main.go:3:1: expected declaration, found vec",
926+
"output_type": "error",
927+
"traceback": [
928+
"parsing go files in TempDir \"/tmp/gonb_e532465a\": /tmp/gonb_e532465a/main.go:3:1: expected declaration, found vec"
929+
]
830930
}
831931
],
832932
"source": [
@@ -855,6 +955,71 @@
855955
"vec"
856956
]
857957
},
958+
{
959+
"cell_type": "code",
960+
"execution_count": 9,
961+
"metadata": {},
962+
"outputs": [
963+
{
964+
"name": "stdout",
965+
"output_type": "stream",
966+
"text": [
967+
"a len=0 cap=5 []\n",
968+
"b len=1 cap=5 [1]\n",
969+
"a len=0 cap=5 []\n",
970+
"a len=5 cap=5 [1 0 0 0 0]\n"
971+
]
972+
}
973+
],
974+
"source": [
975+
"func printSlice(s string, x []int) {\n",
976+
"\tfmt.Printf(\"%s len=%d cap=%d %v\\n\",\n",
977+
"\t\ts, len(x), cap(x), x)\n",
978+
"}\n",
979+
"\n",
980+
"%%\n",
981+
"a := make([]int, 0, 5)\n",
982+
"printSlice(\"a\", a)\n",
983+
"b := append(a, 1)\n",
984+
"printSlice(\"b\", b)\n",
985+
"printSlice(\"a\", a)\n",
986+
"\n",
987+
"hdr := (*reflect.SliceHeader)(unsafe.Pointer(&a))\n",
988+
"data := *(*[5]int)(unsafe.Pointer(hdr.Data))\n",
989+
"printSlice(\"a\", data[:])"
990+
]
991+
},
992+
{
993+
"cell_type": "code",
994+
"execution_count": 11,
995+
"metadata": {},
996+
"outputs": [
997+
{
998+
"name": "stdout",
999+
"output_type": "stream",
1000+
"text": [
1001+
"a len=0 cap=5 []\n",
1002+
"a len=1 cap=5 [1000]\n"
1003+
]
1004+
}
1005+
],
1006+
"source": [
1007+
"func printSlice(s string, x []int) {\n",
1008+
"\tfmt.Printf(\"%s len=%d cap=%d %v\\n\",\n",
1009+
"\t\ts, len(x), cap(x), x)\n",
1010+
"}\n",
1011+
"\n",
1012+
"func myAppend(arr *[]int, val int) {\n",
1013+
" *arr = append(*arr, val)\n",
1014+
"}\n",
1015+
"\n",
1016+
"%%\n",
1017+
"a := make([]int, 0, 5)\n",
1018+
"printSlice(\"a\", a)\n",
1019+
"myAppend(&a, 1000)\n",
1020+
"printSlice(\"a\", a)"
1021+
]
1022+
},
8581023
{
8591024
"cell_type": "markdown",
8601025
"metadata": {},
@@ -868,18 +1033,18 @@
8681033
"metadata": {
8691034
"file_extension": ".py",
8701035
"kernelspec": {
871-
"display_name": "Go",
1036+
"display_name": "Go (gonb)",
8721037
"language": "go",
873-
"name": "gophernotes"
1038+
"name": "gonb"
8741039
},
8751040
"language_info": {
8761041
"codemirror_mode": "",
8771042
"file_extension": ".go",
878-
"mimetype": "",
1043+
"mimetype": "text/x-go",
8791044
"name": "go",
8801045
"nbconvert_exporter": "",
8811046
"pygments_lexer": "",
882-
"version": "go1.18.3"
1047+
"version": "go1.25.4"
8831048
},
8841049
"mimetype": "text/x-python",
8851050
"name": "python",

misc/content/2022/06/string-in-golang/string-in-golang.ipynb

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,18 @@
2626
"source": [
2727
"## Tips and Traps\n",
2828
"\n",
29-
"1. `string` is a primitive type in Golang,\n",
30-
" which means a string value has no methods on it\n",
31-
" but instead you have to use built-in functions \n",
32-
" (e.g., `len`)\n",
33-
" or functions in other modules \n",
34-
" (e.g., the `strings` module)\n",
35-
" to manipulate strings.\n",
36-
"\n",
37-
"1. Raw string literals, \n",
29+
"1. In Golang,\n",
30+
" a string is implemented as a struct\n",
31+
" containing a data pointer (pointing to a read-only slice of bytes)\n",
32+
" and a length.\n",
33+
" \n",
34+
"2. Raw string literals, \n",
3835
" delimited by backticks (back quotes), \n",
3936
" are interpreted literally. \n",
4037
" They can contain line breaks, \n",
4138
" and backslashes have no special meaning.\n",
4239
" \n",
43-
"2. The built-in function `len` returns the length of bytes of a string. \n",
40+
"3. The built-in function `len` returns the length of bytes of a string. \n",
4441
" It is not necessary the length of unicode characters.\n",
4542
" For example,\n",
4643
" calling `len` on a Chinese character returns 3 instead of 1. "

misc/content/2022/06/tips-on-golang/tips-on-golang.ipynb

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"source": [
77
"- Author: Benjamin Du\n",
88
"- Date: 2022-06-04 17:56:46\n",
9-
"- Modified: 2025-11-21 10:56:22\n",
9+
"- Modified: 2025-11-28 14:15:20\n",
1010
"- Title: Tips on Golang\n",
1111
"- Slug: tips-on-golang\n",
1212
"- Category: Computer Science\n",
@@ -24,13 +24,25 @@
2424
"cell_type": "markdown",
2525
"metadata": {},
2626
"source": [
27-
"The package `main` tells the Go compiler that \n",
28-
"the package should compile as an executable program instead of a shared library. \n",
29-
"The `main` function in the `main` package is the entry point of the program.\n",
27+
"## Tips and Traps\n",
3028
"\n",
31-
" mkdir myproj\n",
32-
" cd myproj\n",
33-
" go mod init legendu.net/myproj"
29+
"\n",
30+
"1. The package `main` tells the Go compiler that \n",
31+
" the package should compile as an executable program instead of a shared library. \n",
32+
" The `main` function in the `main` package is the entry point of the program.\n",
33+
" \n",
34+
" mkdir myproj\n",
35+
" cd myproj\n",
36+
" go mod init legendu.net/myproj\n",
37+
"\n",
38+
"2. You can play with Golang code in Go Playground.\n",
39+
" Even better,\n",
40+
" you can play with Golang code in a JupyterLab notebook using\n",
41+
" [gonb](https://github.com/janpfeifer/gonb)\n",
42+
" .\n",
43+
" A pre-compile Docker images is also available at \n",
44+
" [janpfeifer/gonb_jupyterlab](https://hub.docker.com/r/janpfeifer/gonb_jupyterlab)\n",
45+
" ."
3446
]
3547
},
3648
{

0 commit comments

Comments
 (0)