zyj's Blog

  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

go基础巩固

发表于 2018-08-09 | 更新于 2019-06-04 | 分类于 go | 评论数:

go基础巩固

_(下划线)

下划线是一个特殊的变量名,任何赋予它的值都会被丢弃

iota

Go里面有一个关键字iota,这个关键字用来声明enum的时候采用,它默认开始值是0,const中每增加一行加1

make,new操作符

内建函数new本质上说跟其它语言中的同名函数功能一样:new(T)分配了零值填充的T类型的内存空间,并且返回其地址,即一个*T类型的值。用Go的术语说,它返回了一个指针,指向新分配的类型T的零值。

1
new  返回指针

内建函数make(T, args)与new(T)有着不同的功能,make只能创建slice、map和channel,并且返回一个有初始值(非零)的T类型,而不是*T。本质来讲,导致这三个类型有所不同的原因是指向数据结构的引用在使用前必须被初始化。例如,一个slice,是一个包含指向数据(内部array)的指针、长度和容量的三项描述符;在这些项目被初始化之前,slice为nil。对于slice、map和channel来说,make初始化了内部的数据结构,填充适当的值

1
make返回初始化后的(非零)值。
阅读全文 »

go命令

发表于 2018-08-08 | 更新于 2019-06-04 | 分类于 go | 评论数:

GO 命令

go build

说明

这个命令主要用于编译代码。

  1. 如果是普通包(不是main包) go build 命令不会生成任何文件
  2. 如果是main包,go build命令会在当前目录(执行命令的目录)生成二进制文件
  3. 如果某个项目文件夹下有多个文件,而你只想编译某个文件,就可在go build之后加上文件名,例如go build a.go;go build命令默认会编译当前目录下的所有go文件
  4. go build后面跟目录,是相对于GOPATH下的src目录,例如:go build hello,找的是$GOPATH/src/hello目录
  5. go build 不会递归编译,只会编译当前目录
  6. go build会忽略目录下以“_”或“.”开头的go文件

    常用参数

    -i:编译同时安装相应的包= build +install
    -o:编译同时指定生成的文件名
    -n:把需要执行的编译命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的
    -x:打印出来执行的命令,其实就是和-n的结果类似,只是这个会执行
    -v 打印出来我们正在编译的包名
    -compiler name 指定相应的编译器,gccgo还是gc
阅读全文 »

go语言学习接口与方法

发表于 2018-08-07 | 更新于 2019-06-04 | 分类于 go | 评论数:

方法

Go 没有类。不过你可以为结构体类型定义方法。

方法就是一类带特殊的 接收者 参数的函数。
方法接收者在它自己的参数列表内,位于 func 关键字和方法名之间。

1
2
3
4
5
6
7
8
9
10
type v struct {
x, y int
}

func (test v) Abs() int{
return math.Sqrt(v.x*v.x + v.y*v.y)
}
//使用
test := v{1,2}
test.Abs()

记住:方法只是个带接收者参数的函数。

你也可以为非结构体类型声明方法。
1
2
3
4
5
6
7
8
9
10
11
12
type MyFloat float64
func (f MyFloat) Abs() float64{

if f<0 {
return float64(-f)
}else{
return float64(f)
}
}
//使用
f := MyFloat(-math.Sqrt2)
f.Abs()
指针接收者

你可以为指针接收者声明方法。
这意味着对于某类型 T,接收者的类型可以用 *T 的文法。
指针接收者的方法可以修改接收者指向的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}

func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}

func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs())
v.Scale(10)
fmt.Println(v.Abs())
}
//返回
5
50
方法与指针重定向

带指针参数的函数必须接受一个指针
以指针为接收者的方法被调用时,接收者既能为值又能为指针

接受一个值作为参数的函数必须接受一个指定类型的值
而以值为接收者的方法被调用时,接收者既能为值又能为指针

选择值或指针作为接收者

使用指针接收者的原因有二:

首先,方法能够修改其接收者指向的值。

其次,这样可以避免在每次调用方法时复制该值。若值的类型为大型结构体时,这样做会更加高效

接口

接口类型 是有一组方法签名定义的集合
接口类型的变量可以保存任何实现了这些方法的值

接口与隐式实现

类型通过实现一个接口的所有方法来实现该接口
隐式接口从接口的实现中解耦了定义,这样接口的实现可以出现在任何包中,无需提前准备
因此,也就无需在每一个实现上增加新的接口名称,这样同时也鼓励了明确的接口定义
在内部,接口值可以看做包含值和具体类型的元组:
(value, type)
接口值保存了一个具体底层类型的具体值
接口值调用方法时会执行其底层类型的同名方法

底层值为 nil 的接口值

即便接口内的具体值为 nil,方法仍然会被 nil 接收者调用。

在一些语言中,这会触发一个空指针异常,但在 Go 中通常会写一些方法来优雅地处理它(如本例中的 M 方法)。

注意: 保存了 nil 具体值的接口其自身并不为 nil。

空接口

指定了零个方法的接口值被称为 空接口:

1
interface{}

空接口可保存任何类型的值。(因为每个类型都至少实现了零个方法。)
空接口被用来处理未知类型的值。例如,fmt.Print 可接受类型为 interface{} 的任意数量的参数。

类型断言

类型断言提供了访问接口值底层具体值的方式

1
2
3
4
t := i.(T)
//t为接口底层的值
t,ok := i.(T)
//ok返回ture或者false
类型选择

类型选择 是一种按顺序从几个类型断言中选择分支的结构。

类型选择与一般的 switch 语句相似,不过类型选择中的 case 为类型(而非值), 它们针对给定接口值所存储的值的类型进行比较。

1
2
3
4
5
6
7
8
switch v := i.(type){ //注意:type为关键字
case T:
// v 的类型为 T
case S:
// v 的类型为 S
default:
// 没有匹配,v 与 i 的类型相同
}

类型选择中的声明与类型断言 i.(T) 的语法相同,只是具体类型 T 被替换成了关键字 type。

此选择语句判断接口值 i 保存的值类型是 T 还是 S。在 T 或 S 的情况下,变量 v 会分别按 T 或 S 类型保存 i 拥有的值。在默认(即没有匹配)的情况下,变量 v 与 i 的接口类型和值相同。

练习:Stringer

通过让 IPAddr 类型实现 fmt.Stringer 来打印点号分隔的地址。

例如,IPAddr{1, 2, 3, 4} 应当打印为 “1.2.3.4”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.

func (ipAddr IPAddr) String() string {
return fmt.Sprintf("%v.%v.%v.%v", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3])
}

func main() {
hosts := map[string]IPAddr{
"loopback": {127, 0, 0, 1},
"googleDNS": {8, 8, 8, 8},
}

for name, ip := range hosts {
fmt.Printf("%v: %v\n", name, ip)
}
}
错误

Go 程序使用 error 值来表示错误状态。

与 fmt.Stringer 类似,error 类型是一个内建接口:

1
2
3
type error interface {
Error() string
}

(与 fmt.Stringer 类似,fmt 包在打印值时也会满足 error。)

通常函数会返回一个 error 值,调用的它的代码应当判断这个错误是否等于 nil 来进行错误处理。

1
2
3
4
5
6
i, err := strconv.Atoi("42")
if err != nil {
fmt.Printf("couldn't convert number: %v\n", err)
return
}
fmt.Println("Converted integer:", i)

error 为 nil 时表示成功;非 nil 的 error 表示失败。

Reader

io 包指定了 io.Reader 接口,它表示从数据流的末尾进行读取。

Go 标准库包含了该接口的许多实现,包括文件、网络连接、压缩和加密等等。

io.Reader 接口有一个 Read 方法:

func (T) Read(b []byte) (n int, err error)
Read 用数据填充给定的字节切片并返回填充的字节数和错误值。在遇到数据流的结尾时,它会返回一个 io.EOF 错误。

示例代码创建了一个 strings.Reader 并以每次 8 字节的速度读取它的输出。

go语言学习更多类型结构体,数组,切片和映射

发表于 2018-08-07 | 更新于 2019-06-04 | 分类于 go | 评论数:

指针

Go拥有指针。指针保存了值的内存地址。
类型*T 指向T类型值的指针。
&操作符会生成一个指向其操作数的指针。
*操作符表示指针指向的底层值
与c不同,Go没有指针运算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
i, j := 42, 2701

p := &i // point to i
fmt.Println(*p) // read i through the pointer
*p = 21 // set i through the pointer
fmt.Println(i) // see the new value of i

p = &j // point to j
*p = *p / 37 // divide j through the pointer
fmt.Println(j) // see the new value of j
}
阅读全文 »

mac使用配置proxychains-ng

发表于 2018-08-06 | 更新于 2019-06-04 | 分类于 mac | 评论数:

安装proxychains-ng

1
brew install proxychains-ng

修改配置文件(/usr/local/etc/proxychains.conf)

最后一行修改为:1086为socks5 端口,视自己的shadowsocks设置而定(shadowsocks-x默认为1080,shadowsocks-ng默认为1086)

1
socks5  127.0.0.1 1086

使用方法

在执行命令之前添加 : proxychains4,如下:

1
proxychains4 curl ip.cn

特别注意:

mac os sierra 因为安全机制并不能成功代理!

阅读全文 »

go流程控制结构

发表于 2018-08-06 | 更新于 2019-06-04 | 分类于 go | 评论数:

go语言学习-(流程控制语句:for、if、else、switch、defer)

for

Go只有一种循环结构: for循环
Go的for语句后面没有小括号()大括号{}是必须的
初始化语句和后置语句是可选的

1
2
3
4
5
6
7
8
9
for a=0;a<10;a++{

}

for ;a<10; {
}
//上面可以去掉;就等于c语言中的while
for a<10 {
}
阅读全文 »

go包变量和函数

发表于 2018-08-05 | 更新于 2019-06-04 | 分类于 go | 评论数:

GO语言学习-(包,变量,函数)

包

每个go程序都有包构成。
程序从main包开始运行。
按照约定:包名与导入路径的最后一个元素一只。

导入

1
2
3
4
5
6
7
8
//分组导入(更好)
import(
"fmt"
"math"
)
//多条导入
import fmt
import math
阅读全文 »

go代码工作空间

发表于 2018-08-05 | 更新于 2019-06-04 | 分类于 go | 评论数:

go语言学习-go代码工作空间

go代码工作空间

go代码必须放置在工作空间内,它其实就是一个目录,其中包含三个子目录。

1. src 目录

目录包含Go的源文件,它们被组织成包(每个目录都对应一个包)

1
export GOPATH=~/workspace/go
2. pkg 目录

pkg 目录包含包对象

3. bin 目录

bin目录包含可执行命令

4. 将bin目录加入系统path
1
export PATH=$path:$GOPATH/bin

这样在任何地方都可执行go可执行文件

5. go 环境查看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/zyj/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/zyj/workspace/go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/q1/_vk1dvf156701f1zfhgvv5rm0000gp/T/go-build170346034=/tmp/go-build -gno-record-gcc-switches -fno-common"

shadowsocks自定义代理规则user-rule设置方法

发表于 2018-08-03 | 更新于 2019-06-04 | 分类于 shadowsocks | 评论数:

最新版本的shadowsocks支持用户自定义代理规则,更新到最新的版本的shadowsocks后, 在shadowsocks文件夹内会有一个user-rule.txt文档,如果用户需要添加自定义代理规则,只需要编辑user-rule.txt文件。
自定义代理规则设置语法与GFWlist相同,即Adblock Plus filters explained。

规则说明

1. 通配符支持,如*.baidu.com/,实际书写时可省略 *号
1
*.baidu.com
2. 正则表达式支持,以\开始和结束
1
\[\w]+:Wexample.com\
3.例外规则(满足@@后规则的地址不使用代理)
1
@@*.example.com/*
4.用|符号,匹配地址开始和结束
1
2
|http:example.com
example.com|
5.||标记,匹配协议
1
||example.com
6.注释!
1
!Comment

注意:user-rule.txt中的规则并不能直接被shadowsocks使用,如要添加到user-rule.txt中的规则生效,你还要执行下面重要的一步:更新本地的PAC,更新后user-rule.txt中的自定义规则会添加到PAC.txt文件内。(备注:每次编辑完user-rule.txt后,均需执行“从GFWList更新本地PAC”,使本次规则也生效。)

git命令复习

发表于 2018-07-29 | 更新于 2019-08-19 | 评论数:

git 命令复习

参考链接:Git Cheat Sheet 中文版

配置

命令 说明
git config --list 列出当前配置
git config --local --list 列出当前仓库配置
git config --global --list 列出全局配置
git config --system --list 列出系统配置
git config --global user.name "zyj" 设置用户名
git config --global user.email 设置用户的邮箱
阅读全文 »
12345
ZYJ

ZYJ

代码改变世界

47 日志
16 分类
30 标签
RSS
GitHub E-Mail
友情链接
  • 风雪之隅
  • 阮一峰的网络日志
0%
© 2019 ZYJ
由 Hexo 强力驱动 v3.8.0
|
主题 – NexT.Gemini v6.7.0