goland 基础笔记 - Go语言中文社区

goland 基础笔记


目录

1、保留字段

2、预声明的常量、类型和函数

3、函数变参

4、defer延迟函数

4.1、修改函数返回值:

4.2、defer后进先出(LIFO):

5、map把函数作为value

6、defer、panic、recover

7、if

8、构建自定义包:

9、常用包:

10、自定义类型:

11、struct(method)

12、struct(匿名字段)

13、合法类型转换:

14、interface

15、interface、switch、reflect:

16、goroutine:

17、channel:

18、select:

19、获取url:

20、获取多个url:

21、简单的web服务器:


 

 

 

1、保留字段

break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

2、预声明的常量、类型和函数

3、函数变参

func main() {
	a := [...]int{1,2,3}
	test1(a[:]...)
}

func test1(arg ...int) {
	for n := range arg {
		fmt.Printf("And the number is: %dn", n)
	}
}

4、defer延迟函数

当前函数执行完之后,退出之前调用

4.1、修改函数返回值:

func main() {
	print(test1())
}

func test1() (result int) {
	defer func() {
		result++
	}()
	return 0
}

结果:
1

4.2、defer后进先出(LIFO):

func main() {
	for i := 0; i < 5; i++ {
		defer fmt.Printf("%d ", i)
	}
}

结果:
4 3 2 1 0 

5、map把函数作为value

func main() {
	var xs = map[int]func() int{
		1: func() int { return 10 },
		2: func() int { return 20 },
		3: func() int { return 30 },
	}
	print(xs[1]())
}

结果:
10

6、defer、panic、recover

如果当前的goroutine 产生了panic,这个defer 函数能够发现

func main() {
	defer func() {
		fmt.Println("c")
		if err := recover(); err != nil {
			fmt.Println(err)
		}
		fmt.Println("d")
	}()
	test1()
}

func test1() {
	fmt.Println("a")
	panic(55)
	fmt.Println("b")
	fmt.Println("f")
}

结果:
a
c
55
d

7、if

在if之后,条件语句之前,可以添加变量的初始化语句,使用;间隔

func main() {
	a := 1
	b := false
	if b, a = true, 2; b == false && a == 2 {

	}
}

8、构建自定义包:

这里注意,被调用的函数名首字母必须大写(小写为私有函数),不然调用不了

package test1

import "fmt"

func TestPrint() {
	fmt.Println("test1")
}

然后放到GOPATH/Test1目录下

在cmd执行  go install test1,会在pkg目录下生成二进制文件

然后就可以直接调用了

package main

import "test1"

func main() {
	test1.TestPrint()
}

9、常用包:

fmt 包fmt 实现了格式化的I/O 函数,这与C 的printf 和scanf 类似。格式化短语派生于C。一些短语(%-序列)这样使用:
%v:默认格式的值。当打印结构时,加号(%+v)会增加字段名;
%#v:Go 样式的值表达;
%T:带有类型的Go 样式的值表达;
io 这个包提供了原始的I/O 操作界面。它主要的任务是对os 包这样的原始的I/O 进行封装,增加一些其他相关,使其具有抽象功能用在公共的接口上。
bufio 这个包实现了缓冲的I/O。它封装于io.Reader 和io.Writer 对象,创建了另一个对象(Reader 和Writer)在提供缓冲的同时实现了一些文本I/O 的功能。
sort sort 包提供了对数组和用户定义集合的原始的排序功能。
strconv strconv 包提供了将字符串转换成基本数据类型,或者从基本数据类型转换为字符串的功能。
os os 包提供了与平台无关的操作系统功能接口。其设计是Unix 形式的。
sync sync 包提供了基本的同步原语,例如互斥锁。
flag flag 包实现了命令行解析。
json json 包实现了编码与解码RFC 4627 定义的JSON 对象。
template 数据驱动的模板,用于生成文本输出,例如HTML。
将模板关联到某个数据结构上进行解析。模板内容指向数据结构的元素(通常结构的字段或者map 的键)控制解析并且决定某个值会被显示。模板扫描结构以便解析,而“游标”@ 决定了当前位置在结构中的值。
http http 实现了HTTP 请求、响应和URL 的解析,并且提供了可扩展的HTTP 服务和基本的HTTP 客户端。
unsafe unsafe 包包含了Go 程序中数据类型上所有不安全的操作。通常无须使用这个。
reflect reflect 包实现了运行时反射,允许程序通过抽象类型操作对象。通常用于处理静态类型interface{} 的值,并且通过Typeof 解析出其动态类型信息,通常会返回一个有接口类型Type 的对象。包含一个指向类型的指针,*StructType、*IntType 等等,描述了底层类型的详细信息。可以用于类型转换或者类型赋值。
exec exec 包执行外部命令。

10、自定义类型:

func main() {
	type foo int
	var a foo
	a = 1
	print(a)
}

11、struct(method)

创建一个工作在这个类型上的函数,方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,而不仅仅是struct

自定义类型和方法必须在同一个包

这里func (t *T) printT() 中使用指针 *T 是因为需要值传递

import "fmt"

type T struct {
	Name string
	Age  int
}

func (t *T) printT() {
	fmt.Println(t.Age, t.Name)
}

func main() {
	t := T{}
	fmt.Println(t)
	t.Name = "back"
	t.Age = 10
	fmt.Println(t)
	t.printT()
}

结果:
{ 0}
{back 10}
10 back

12、struct(匿名字段)

import "fmt"

type T struct {
	string
	int
}

func (t *T) printT() {
	fmt.Println(t)
}

func main() {
	t := T{"Jack", 12}
	fmt.Println(t)
	t.printT()
}

结果:
{Jack 12}
&{Jack 12}

13、合法类型转换:

14、interface

import "fmt"

type S struct{ i int }
func (p *S) Get() int { return p.i }
func (p *S) Put(v int) { p.i = v }

type I interface {
	Get() int
	Put(int)
}

func main() {
	var i I
	i = new(S)
	i.Put(2)
	fmt.Println(i.Get())
}

结果:
2

15、interface、switch、reflect:

只有公有变量才能反射

import (
	"fmt"
	"reflect"
)

type S struct{
	Ii int "tag:int"
	Jj bool "tag:bool"
}

func (p *S) Get() int  { return p.Ii }
func (p *S) Put(v int) { p.Ii = v }

type R struct{ i int }

func (p *R) Get() int  { return p.i }
func (p *R) Put(v int) { p.i = v }

type I interface {
	Get() int
	Put(int)
}

func f(p I) {
	switch p.(type) {
	case *S:
		{
			t := reflect.TypeOf(p)
			v := reflect.ValueOf(p)
			fmt.Println(v)
			tag := t.Elem().Field(1).Tag
			v.Elem().Field(1).SetBool(true)
			name := v.Elem().Field(1).Bool()
			fmt.Println(tag)
			fmt.Println(name)
		}
	case *R:
	default:
	}
}

func main() {
	var s S
	f(&s)
}

结果:
&{0 false}
tag:bool
true

16、goroutine:

这里如果没有最后一句 time.Sleep(5 * 1e9),则两个goroutine中的内容都不会打印,这就需要channel了。

虽然goroutine 是并发执行的,但是它们并不是并行运行的。如果不告诉Go 额外的东西,同一时刻只会有一个goroutine 执行。利用runtime.GOMAXPROCS(n) 可以设置goroutine 并行执行的数量。

import (
	"fmt"
	"time"
)

func ready(w string, sec int64) {
	time.Sleep(time.Duration(sec * 1e9))
	fmt.Println(w, "is ready!")
}
func main() {
	go ready("Tee", 2)
	go ready("Coffee", 1)
	fmt.Println("I'm waiting")
	time.Sleep(5 * 1e9)
}

结果:
I'm waiting
Coffee is ready!
Tee is ready!

17、channel:

两个<-c,收到的值都被丢弃了,两次是因为有两个goroutine

import (
	"fmt"
	"time"
)

var c chan int

func ready(w string, sec int64) {
	time.Sleep(time.Duration(sec * 1e9))
	fmt.Println(w, "is ready!")
	c <- 1
}
func main() {
	c = make(chan int)
	go ready("Tee", 2)
	go ready("Coffee", 1)
	fmt.Println("I'm waiting")
	<-c
	<-c
}
必须使用make 创建channel:
ci := make(chan int)
cs := make(chan string)
cf := make(chan interface{})

接收:
ci <- 1 ← 发送整数1 到channel ci
<-ci ← 从channel ci 接收整数
i := <-ci ← 从channel ci 接收整数,并保存到i 中

18、select:

循环接收

import (
	"fmt"
	"time"
)

var c chan int

func ready(w string, sec int64) {
	time.Sleep(time.Duration(sec * 1e9))
	fmt.Println(w, "is ready!")
	c <- 1
}

func main() {
	c = make(chan int)
	go ready("Tee", 2)
	go ready("Coffee", 1)
	fmt.Println("I'm waiting")
	for i := 0; i < 2; i++ {
		select {
		case <-c:
		}
	}
}

19、获取url:

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

func main() {
	url := "http://www.kuaidi100.com/query?type=yuantong&postid=11111111111"
	resp, err := http.Get(url)
	if err != nil {
		fmt.Fprintf(os.Stderr, "fetch: %vn", err)
		os.Exit(1)
	}
	b, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err!= nil {
		fmt.Fprintf(os.Stderr, "fetch: reading %s: %vn", url, err)
		os.Exit(1)
	}
	fmt.Printf("%s", b)
}

20、获取多个url:

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"time"
)

func main() {
	url := []string{
		"http://www.kuaidi100.com/query?type=yuantong&postid=11111111111",
		"http://www.kuaidi100.com/query?type=yuantong&postid=12345678901",
		"http://baike.baidu.com/api/openapi/BaikeLemmaCardApi?scope=103&format=json&appid=379020&bk_key=%E9%95%BF%E6%B2%99&bk_length=600",
	}
	start := time.Now()
	ch := make(chan string)
	for _, urlT := range url{
		go fetch(urlT, ch)
	}
	for range url[:] {
		fmt.Println(<-ch)
	}
	fmt.Printf("%.2fs elapsedn", 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)
		return
	}
	nbytes, err := io.Copy(ioutil.Discard, resp.Body)
	resp.Body.Close()
	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)
}

结果:
0.11s         11    http://baike.baidu.com/api/openapi/BaikeLemmaCardApi?scope=103&format=json&appid=379020&bk_key=%E9%95%BF%E6%B2%99&bk_length=600
0.17s       1301    http://www.kuaidi100.com/query?type=yuantong&postid=11111111111
0.17s       2189    http://www.kuaidi100.com/query?type=yuantong&postid=12345678901
0.17s elapsed

21、简单的web服务器:
 

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "URL.Path = %qn", r.URL.Path)
	fmt.Printf("URL.Path = %qn", r.URL.Path)
}

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Dopamy_BusyMonkey/article/details/89029162
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-02-25 00:09:57
  • 阅读 ( 2150 )
  • 分类:Goland

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢