YWJL 2 år sedan
förälder
incheckning
7dc8117b73

+ 11 - 0
Go语言核心36讲/06/main.go

@@ -9,3 +9,14 @@ func main() {
 		fmt.Println(nums[i])
 	}
 }
+
+func fun1() {
+	fmt.Println("hello")
+	values := []string{"1", "2", "3"}
+	value1 := interface{}(values)
+	fmt.Println(value1)
+	value, ok := interface{}(values).([]string)
+	fmt.Println(value, ok)
+	test := "97"
+	fmt.Println(string(test))
+}

+ 66 - 0
Go语言核心36讲/07/main.go

@@ -0,0 +1,66 @@
+package main
+
+import "fmt"
+
+func add1(s []int, x int) []int {
+	s = append(s, x)
+	fmt.Printf("add1-addrness:%p", &s)
+	fmt.Println("")
+	return s
+
+}
+func add2(s []int, x int) {
+	s = append(s, x)
+}
+func add3(s [10]int, x int) {
+	s[9] = 10
+	fmt.Println(s)
+	fmt.Printf("add1-addrness:%p", &s)
+	fmt.Println("")
+}
+
+func main() {
+	// sliceList()
+	// nums := make([]int, 1)
+	// nums = append(nums, 0)
+	// fmt.Println(nums, len(nums), cap(nums))
+	sliceAppend()
+}
+
+func sliceList() {
+	//切片,引用类型
+	a := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+	fmt.Println(a)
+	s1 := a[5:8] //len=3 cap=5
+	fmt.Println("s1", s1)
+	fmt.Printf("s1-addrness:%p", &s1)
+	fmt.Println("")
+	add1(s1, 0)
+	fmt.Println("a", a)
+	fmt.Println("s1", s1)
+
+	add2(s1, 1)
+	fmt.Println("a", a)
+	fmt.Println("s1", s1)
+	//数组,值类型
+	fmt.Println("值类型-------------------")
+	b := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+	fmt.Printf("b的addrness:%p\n", &b)
+	add3(b, 0)
+	fmt.Println(b)
+}
+
+func sliceAppend() {
+	arr := [5]int{1, 2, 3, 4} // [1 2 3 4 0]
+	fmt.Println(arr)
+
+	s2 := arr[2:] // [3 4 0]
+	printSlice(s2)
+	s2 = append(s2, 5)
+	printSlice(s2)
+	fmt.Println(arr)
+}
+
+func printSlice(s []int) {
+	fmt.Printf("len=%d cap=%d %p %v\n", len(s), cap(s), s, s)
+}

BIN
Go语言核心36讲/07/read.assets/edb5acaf595673e083cdcf1ea7bb966c.png


+ 26 - 0
Go语言核心36讲/07/read.md

@@ -0,0 +1,26 @@
+# 数组和切片
+
+## 不同点
+
+1. 数组类型长度是固定的,切片是可变长的
+2. 组的长度在声明它的时候就必须给定,并且之后不会再改变。可以说,数组的长度是其类型的一部分。比如,[1]string和[2]string就是两个不同的数组类型。
+3. 切片的长度可以自动地随着其中元素数量的增长而增长,但不会随着元素数量的减少而减小
+4. 值字面量的区别![img](read.assets/edb5acaf595673e083cdcf1ea7bb966c.png)
+
+## 有关值类型和值传递
+
+1. 值类型和值传递,不是同一个说法
+2. golang只有值传递,即使传递的是指针类型,如切片、map、通道,也是创建新的指针副本,指针存储地址相同,其指向不同。
+3. 数组是值类型,其创建的副本是在新的内存地址中copy一个完全相同的值类型,这里是数组,所做修改均在新内存空间中。
+4. 而切片是引用类型,其创建的副本是在新的内存地址中copy一个完全引用类型,这里是指针,所做的修改均在新内存空间中,也就是新指针副本中,但新的指针副本,虽然所在内存地址不同,但其指向的内存空间和原指针是一样的。https://www.flysnow.org/2018/02/24/golang-function-parameters-passed-by-value.html
+5. 这里也要记住,引用类型和传引用是两个概念。
+6. 再记住,Go里只有传值(值传递)。
+
+## 有关len()和cap()
+
+1. https://www.cnblogs.com/sunshineliulu/p/12244532.html
+2. 创建切片的时候,如果没特殊说明,cap容量=len长度
+3. cap是指底层数组的长度,len是指当前切片的长度,当前切片取自底层数组
+4. 当前切片扩容时,即append,如果无需对底层数组扩容,则切片的容量和指针地址不会变,但底层数组会变
+5. 如果需要对底层数组扩容,则容量和指针地址会改变,会生成一个新的底层数组,但是它也同时生成了新的切片。它只是把新的切片作为了新底层数组的窗口,而没有对原切片,及其底层数组做任何改动。
+

+ 8 - 0
go圣经/.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/

+ 8 - 0
go圣经/.idea/go圣经.iml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 8 - 0
go圣经/.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/go圣经.iml" filepath="$PROJECT_DIR$/.idea/go圣经.iml" />
+    </modules>
+  </component>
+</project>

+ 10 - 0
go圣经/1.1/main.go

@@ -0,0 +1,10 @@
+package main
+
+import "fmt"
+
+func main() {
+	s := "test"
+	// s = 1
+	fmt.Println("Hello, 世界")
+	fmt.Println(s)
+}

+ 15 - 0
go圣经/1.2/main.go

@@ -0,0 +1,15 @@
+package main
+
+import (
+	"fmt"
+	"os"
+)
+
+func main() {
+	s, sep := "", ""
+	for _, arg := range os.Args[0:] {
+		s += sep + arg
+		sep = " "
+	}
+	fmt.Println(s)
+}

+ 5 - 0
go圣经/1.3/aaa.txt

@@ -0,0 +1,5 @@
+111
+222
+333
+end!
+333

+ 28 - 0
go圣经/1.3/dup1.go

@@ -0,0 +1,28 @@
+// Dup1 prints the text of each line that appears more than
+// once in the standard input, preceded by its count.
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"os"
+)
+
+func DUP1() {
+	fmt.Printf("----------dup1 start ---------------")
+	counts := make(map[string]int) //映射,key是string、value是int
+	input := bufio.NewScanner(os.Stdin)  //读取 终端输入
+	fmt.Printf("please input:\n")
+	for input.Scan() && input.Text() != "end!" {
+		counts[input.Text()]++
+		// fmt.Printf("value:%s\n", input.Text())
+	}
+	// NOTE: ignoring potential errors from input.Err()
+	fmt.Printf("\ninput end!\n")
+	for line, n := range counts {
+		// if n > 1 {
+		fmt.Printf("%d\t%s\n", n, line)
+		// }
+	}
+	fmt.Printf("----------dup1 end ---------------")
+}

+ 49 - 0
go圣经/1.3/dup2.go

@@ -0,0 +1,49 @@
+// Dup2 prints the count and text of lines that appear more than once
+// in the input.  It reads from stdin or from a list of named files.
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"os"
+)
+
+func Test() {
+	fmt.Printf("test message!")
+}
+
+func DUP2() {
+	counts := make(map[string]int)
+	files := os.Args[1:]
+	for _,value := range files {
+		f,err :=os.Open(value)
+		fmt.Printf("内容:%s\n",value)
+		fmt.Print(f,err) // 地址
+	}
+
+	if len(files) == 0 {
+		countLines(os.Stdin, counts)
+	} else {
+		for _, arg := range files {
+			f, err := os.Open(arg)
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "dup2: %v\n", err)
+				continue
+			}
+			countLines(f, counts)
+			f.Close()
+		}
+	}
+	for line, n := range counts {
+		fmt.Printf("%d\t%s\n", n, line)
+	}
+}
+
+//这里是读的文件内容
+func countLines(f *os.File, counts map[string]int) {
+	input := bufio.NewScanner(f)
+	for input.Scan() && input.Text() != "end!" {  //读取file的输入.--todo:这里的读取过程,会报错么,该怎么改
+		counts[input.Text()]++
+	}
+	// NOTE: ignoring potential errors from input.Err()
+}

+ 25 - 0
go圣经/1.3/dup3.go

@@ -0,0 +1,25 @@
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"strings"
+)
+
+func DUP3() {
+	counts := make(map[string]int)
+	for _, filename := range os.Args[1:] {
+		data, err := ioutil.ReadFile(filename)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "dup3: %v\n", err)
+			continue
+		}
+		for _, line := range strings.Split(string(data), "\n") { //读取文件,以\n分割,统计key\value
+			counts[line]++
+		}
+	}
+	for line, n := range counts {
+		fmt.Printf("%d\t%s\n", n, line)
+	}
+}

+ 30 - 0
go圣经/1.3/main.go

@@ -0,0 +1,30 @@
+// Dup1 prints the text of each line that appears more than
+// once in the standard input, preceded by its count.
+package main
+
+import "fmt"
+
+func main() {
+	//这里是 代码包 共享变量的测试
+
+	// dup1
+	//fmt.Printf("dup1:\n")
+	//Dup1()
+
+	//dup2
+	//fmt.Printf("dup2:\n")
+	//DUP2()
+	//fmt.Printf("dup3:\n")
+	//DUP3()
+	counts := make(map[string]int)
+	fatherCounts := make(map[string]map[string]int)
+	counts["A"] = 1
+	counts["B"] = 2
+	fatherCounts["A"] = counts
+	fmt.Printf("%d\n",counts["A"])
+	delete(fatherCounts["A"],"A")
+	fmt.Printf("A:%d,B:%d,C:%d\n", fatherCounts["A"]["A"],fatherCounts["A"]["B"],fatherCounts["A"]["C"]) //默认值会赋0
+	for key := range fatherCounts {
+		fmt.Printf("key:%s",key)
+	}
+}

BIN
go圣经/1.4/1.4.exe


+ 56 - 0
go圣经/1.4/main.go

@@ -0,0 +1,56 @@
+// Lissajous generates GIF animations of random Lissajous figures.
+package main
+
+import (
+	"image"
+	"image/color"
+	"image/gif"
+	"io"
+	"math"
+	"math/rand"
+	"os"
+	"time"
+)
+
+var palette = []color.Color{color.White, color.Black}
+
+const (
+	whiteIndex = 0 // first color in palette
+	blackIndex = 1 // next color in palette
+)
+
+func main() {
+	// The sequence of images is deterministic unless we seed
+	// the pseudo-random number generator using the current time.
+	// Thanks to Randall McPherson for pointing out the omission.
+	rand.Seed(time.Now().UTC().UnixNano())
+	lissajous(os.Stdout)
+}
+
+func lissajous(out io.Writer) {
+	const (
+		cycles  = 5     // number of complete x oscillator revolutions
+		res     = 0.001 // angular resolution
+		size    = 100   // image canvas covers [-size..+size]
+		nframes = 64    // number of animation frames
+		delay   = 8     // delay between frames in 10ms units
+	)
+
+	freq := rand.Float64() * 3.0 // relative frequency of y oscillator
+	anim := gif.GIF{LoopCount: nframes}
+	phase := 0.0 // phase difference
+	for i := 0; i < nframes; i++ {
+		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
+		img := image.NewPaletted(rect, palette)
+		for t := 0.0; t < cycles*2*math.Pi; t += res {
+			x := math.Sin(t)
+			y := math.Sin(t*freq + phase)
+			img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5),
+				blackIndex)
+		}
+		phase += 0.1
+		anim.Delay = append(anim.Delay, delay)
+		anim.Image = append(anim.Image, img)
+	}
+	gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors
+}

BIN
go圣经/1.4/out1.gif


BIN
go圣经/1.5/1.5.exe


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 3 - 0
go圣经/1.5/1.html


+ 0 - 0
go圣经/1.5/2.html


+ 19 - 0
go圣经/1.5/deferTest.go

@@ -0,0 +1,19 @@
+// 有关defer 延迟的执行顺序的粗略测试
+package main
+
+import "fmt"
+
+func Test() int{
+	a := 1
+	defer func() {
+		fmt.Println("__1",a)
+		a = 4
+		fmt.Println("__2",a)
+	}()
+	fmt.Println("__3",a)
+	return a
+}
+
+func deferTest() {
+	fmt.Printf("return:,%d",Test())
+}

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
go圣经/1.5/demo.html


+ 45 - 0
go圣经/1.5/main.go

@@ -0,0 +1,45 @@
+// Fetch prints the content found at a URL.
+package main
+
+import (
+	"fmt"
+	"io"
+	"net/http"
+	"os"
+	"strings"
+)
+
+func main() {
+	for _, url := range os.Args[1:] {
+		if strings.HasPrefix(url, "http://") {
+			fmt.Println("url:",url)
+		} else {
+			url =  "http://" + url
+			fmt.Println("url:",url)
+		}
+		resp, err := http.Get(url)  //请求命令行参数传入的url
+		fmt.Println("httpCode:",resp.Status)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
+			os.Exit(1)
+		}
+		//创建文件
+		fp, err := os.Create("./demo.html")  // 如果文件已存在,会将文件清空。
+		fmt.Println(fp, err)  // &{0xc000076780} <nil>
+		fmt.Println("%T???", fp)  // *os.File 文件指针类型
+		if err != nil {
+			fmt.Println("文件创建失败")
+			//创建文件失败的原因有:
+			//1、路径不存在  2、权限不足  3、打开文件数量超过上限  4、磁盘空间不足等
+			return
+		}
+		b, err := io.Copy(fp, resp.Body)  //读body中的数据,放到内存
+		if err != nil {
+			fmt.Println("iO.Copy函数报错")
+			return
+		}
+		fp.Close()
+		resp.Body.Close()
+		fmt.Printf("b:%d", b)  //打印出来
+	}
+}

+ 42 - 0
go圣经/1.6/main.go

@@ -0,0 +1,42 @@
+// Fetchall fetches URLs in parallel and reports their times and sizes.
+//两个函数 goroutine 通过 chan 进行 数据通信
+// chan 存在 死锁,必须一方发、一方收。
+package main
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"os"
+	"time"
+)
+
+func main() {
+	start := time.Now()
+	ch := make(chan string)
+	for _, url := range os.Args[1:] {
+		go fetch(url, ch) // start a goroutine
+	}
+	for range os.Args[1:] {
+		fmt.Println(<-ch) // receive from channel ch
+	}
+	fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
+}
+
+func fetch(url string, ch chan<- string) {
+	start := time.Now()
+	resp, err := http.Get(url)
+	if err != nil {
+		ch <- fmt.Sprint(err) // send to channel ch
+		return
+	}
+	nbytes, err := io.Copy(ioutil.Discard, resp.Body)
+	resp.Body.Close() // don't leak resources
+	if err != nil {
+		ch <- fmt.Sprintf("while reading %s: %v", url, err)
+		return
+	}
+	secs := time.Since(start).Seconds()
+	ch <- fmt.Sprintf("%.2fs  %7d  %s", secs, nbytes, url)
+}

+ 2 - 0
go圣经/readme.md

@@ -0,0 +1,2 @@
+不知道为什么,无法在.vscode目录下运行这里面的部分代码。
+尤其是例如1.3这样的包含多个.go文件的工作区

Vissa filer visades inte eftersom för många filer har ändrats