不灭的焱

革命尚未成功,同志仍须努力

作者:php-note.com  发布于:2017-01-22 09:14  分类:Go/Python  编辑

上一篇文章 说到了 Golang 中的反射的一些基本规则,重点就是文章中最后的三点,但是这篇文章并没有说如何在反射中调用函数和方法,这就是接下来要说的。

反射中调用 函数

众所周知,Golang 中的函数是可以像普通的 int、float 等类型变量那样作为值的,例如:

package main

import "fmt"

func hello() {
	fmt.Println("Hello world!")
}

func main() {
	hl := hello
	hl()
}

prints:

hello world!

既然函数可以像普通的类型变量一样可以的话,那么在反射机制中就和不同的变量是一样的,在反射中 函数 和 方法 的类型(Type)都是 reflect.Func,如果要调用函数的话,可以通过 Value 的 Call() 方法,例如:

func main() {
	hl := hello
	fv := reflect.ValueOf(hl)
	fmt.Println("fv is reflect.Func ?", fv.Kind() == reflect.Func)
	fv.Call(nil)
}

prints:

fv is reflect.Func? true
hello world!

Value 的 Call() 方法的参数是一个 Value 的 slice,对应的反射函数类型的参数,返回值也是一个 Value 的 slice,同样对应反射函数类型的返回值。通过这个例子,相信你一看就明白了:

func prints(i int) string {
	fmt.Println("i =", i)
	return strconv.Itoa(i)
}

func main() {
	fv := reflect.ValueOf(prints)
	params := make([]reflect.Value, 1)                 // 参数
	params[0] = reflect.ValueOf(20)                    // 参数设置为20
	rs := fv.Call(params)                              // rs作为结果接受函数的返回值
	fmt.Println("result:", rs[0].Interface().(string)) // 当然也可以直接是 rs[0].Interface()
}

prints:

i = 20
result: 20
作者:php-note.com  发布于:2017-01-21 09:13  分类:Go/Python  编辑

类型 和 接口

由于反射是基于类型系统(type system)的,所以先简单了解一下类型系统。

首先 Golang 是一种静态类型的语言,在编译时每一个变量都有一个类型对应,例如:int, floate32, []byte, *MyType 等等。如果我们这样声明:

type MyInt int

var i int
var j MyInt

上面的 i 是 int 类型的, j 是 MyInt 类型的。i 和 j 是不同的静态类型,尽管他们都有相同的相关类型(这里就是 int),他们不能互相赋值除非通过强制转换。

一种非常重要的类型分类是接口类型,接口代表中方法的集合。只要一个值实现了接口定义的方法,那么这个值就可以存储这个具体的值。一个著名的例子就是 io 包中的 Reader 和 Writer。

作者:php-note.com  发布于:2017-01-03 09:02  分类:Go/Python  编辑

GOPATH 环境变量用于指定这样一些目录:除 $GOROOT 之外的包含 Go 项目源代码和二进制文件的目录。go install 和 go 工具会用到 GOPATH:作为编译后二进制的存放目的地 和 import 包时的搜索路径。

GOPATH 是一个路径列表,也就是可以同时指定多个目录。多个目录在 Mac 和 Linux 下通过“:”分割,Windows下通过“;”分割。注意,大部分情况下会是第一个路径优先,比如:查找包

作者:php-note.com  发布于:2017-01-03 09:01  分类:Go/Python  编辑

项目目录结构如何组织,一般语言都是没有规定。但 Go 语言这方面做了规定,这样可以保持一致性

1、一般的,一个 Go 项目在 GOPATH 下,会有如下三个目录:

|--bin
|--pkg
|--src

其中,bin存放编译后的可执行文件;pkg 存放编译后的包文件;src 存放项目源文件。一般,bin 和 pkg 目录可以不创建,go 命令会自动创建(如 go install),只需要创建src目录即可。

对于 pkg 目录,曾经有人问:我把 Go 中的包放入 pkg 下面,怎么不行啊?他直接把 Go 包的源文件放入了 pkg 中。这显然是不对的。pkg 中的文件是 Go 编译生成的,而不是手动放进去的。(一般文件后缀.a)

对于 src 目录,存放源文件,Go 中源文件以包(package)的形式组织。通常,新建一个包就在 src 目录中新建一个文件夹。

作者:php-note.com  发布于:2017-01-03 09:00  分类:Go/Python  编辑

有时候 go get 比较慢,可以考虑用迅雷等下载工具下载下来,然后再本地安装,

如:code.google.com/p/go.net/websocket,如何安装这些离线包?

先在你的 GOPATH 目录(如果不懂 GOPATH,请先弄懂)下,创建目录 src

mkdir src

复制 code.google.com.p.go.net.tar.gzsrc 目录下,解压缩,这时候目录应该看起来是这个样子,

作者:php-note.com  发布于:2016-11-17 13:07  分类:Go/Python  编辑

字典是一种内置的数据结构,用来保存 键值对 的 无序集合。

(1)字典的创建

1) make(map[KeyType]ValueType, initialCapacity)

2) make(map[KeyType]ValueType)

3) map[KeyType]ValueType{}

4) map[KeyType]ValueType{key1 : value1, key2 : value2, ... , keyN : valueN}

作者:php-note.com  发布于:2016-11-17 13:06  分类:Go/Python  编辑

一、数组

与其他大多数语言类似,Go语言的数组也是一个元素类型相同的定长的序列。

(1)数组的创建

数组有 3 种创建方式:

1) [length]Type

2) [length]Type{value1, value2, ... , valueN}

作者:php-note.com  发布于:2016-11-14 13:03  分类:Go/Python  编辑

得出以下结论:

1、import 导入的参数是路径,而非包名

2、尽管习惯将包名目录名保证一致,但这不是强制规定;

3、在代码中引用包成员时,使用包名而非目录名

4、同一目录下,所有源文件必须使用相同的包名称(因为导入时使用绝对路径,所以在搜索路径下,包必须有唯一路径,但无须是唯一名字);

5、至于文件名,更没啥限制(扩展名为.go);

作者:php-note.com  发布于:2016-11-14 13:02  分类:Go/Python  编辑

Go变量 初始化

复合类型(数组、切片、字典、结构体)变量的初始化是,有一些语法限制:

1、初始化表达式必须包含类型标签

2、左花括号必须在类型尾部,不能另起一行;

3、多个成员初始值以逗号分隔;

4、允许多行,但每行须以逗号 或 右花括号结束;

作者:php-note.com  发布于:2016-11-13 13:01  分类:Go/Python  编辑

1、谷歌官方维护了一个基于go语言的开源项目列表:https://github.com/golang/go/wiki/Projects

2、[知乎网] 有哪些值得学习的 Go 语言开源项目?