1.查看语言版本
go version
2.下载编辑器,Atom在github上是开源的,官网:https://github.com/atom
3.第一个Go程序
package main
import "fmt"
func main(){
fmt.Println("hello,world")
}
1.测试脚本,执行脚本命令go test -v xxx_test.go
package try_test
import "testing"
func TestFirstTry( t*testing.T){
t.Log("My Frist Try");
}
执行结果:
➜ test go test -v zc_test.go
=== RUN TestFirstTry
zc_test.go:6: My Frist Try
--- PASS: TestFirstTry (0.00s)
PASS
ok command-line-arguments 0.006s
2.声明常量
package main
import "fmt"
func main() {
const LENGTH int = 10
const WIDTH int = 5
var area int
const a, b, c = 1, false, "str" //多重赋值
area = LENGTH * WIDTH
fmt.Printf("面积为 : %d", area)
println()
println(a, b, c)
}
常量还可以用作枚举:
package const_test
import "testing"
func TestConst(t *testing.T) {
const (
Unknown = 0
Female = 1
Male = 2
)
t.Log(Unknown,Female,Male);
}
3.数据类型
package type_test
import "testing"
func TestType(t *testing.T) {
var a int = 1;
var b int64
b = int64(a)
t.Log(a,b);
}
func TestPoint(t *testing.T) {
var a int = 1;
aPtr := &a;
t.Log(a,aPtr);
t.Logf("%T %T",a,aPtr);
}
func TestString(t *testing.T) {
var string string
t.Log("*"+string+"*");
}
4.条件和循环
4.1 for循环
package loop_test
import "testing"
func TestLoopNumber(t *testing.T){
var number int = 0
for number < 5 {
t.Log(number);
number++;
}
}
4.2 if条件语句
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
}
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
} else {
/* 在布尔表达式为 false 时执行 */
}
1.数组声明和遍历
声明数组 var variable_name [SIZE] variable_type
package array_test
import "testing"
func TestArrayInt(t *testing.T) {
var arr [3]int
arr1 := [4]int{1,2,3,4}
arr3 := [...]int{1,3,4,5}
arr1[1] = 5
t.Log(arr[1],arr[2]);
t.Log(arr1,arr3);
}
func TestArrayLoop( t *testing.T ) {
arr1 := [4]int{1,2,3,4}
var count int = len(arr1);
for index := 0; index < count; index ++ {
t.Log(index,arr1[index]);
}
for index,value := range arr1 {
t.Log(index,value)
}
for _,value := range arr1 {
t.Log(value)
}
}
2.数组截取
a[开始索引(包含),结束索引(不包含)]
a := [...]int {1,2,3,4,5}
a[1:2] // 2
a[1:3] // 2,3
a[1:len(a)] // 2,3,4,5
a[1:] //2,3,4,5
a[:3] // 1,2,3
func TestArraySlice(t *testing.T) {
arr := [5]int{0,2,3,4,5}
t.Log(arr[0:2])
}
3.切片类型
3.1切片声明:
package slice_test
import "testing"
func TestSliceInit(t *testing.T) {
var s0 []int
s0 = append(s0,1)
s := []int{}
s1 := []int{1,2,3}
s2 := make([]int, 2,4)
t.Log(len(s0),cap(s0));
t.Log(len(s),cap(s));
t.Log(len(s1),cap(s1));
t.Log(len(s2),cap(s2));
}
4.数组和切片的异同点:
5.Map声明和遍历
package map_test
import "testing"
func TestMapInit(t *testing.T) {
m := map[string]int{"one":1,"two":2,"three":3}
m1 := map[string]int{}
m2 := make(map[string]int, 10)
t.Log(m,m1,m2);
}
func TestMapLoop(t *testing.T) {
m := map[string]int{"one":1,"two":2,"three":3}
for key,value := range m {
t.Log(key,value);
}
}
与其他语言的差异:在访问的key不存在时,扔会返回0值,不能通过返回nil来判断元素是否存在。
6.字符串(与其他主要编程语言的差异)
与其他主要编程语言的差异
package func_test
import "testing"
import "math/rand"
func returnParams() (int ,int){
return rand.Intn(10),rand.Intn(20)
}
func TestFuncParams(t *testing.T) {
a,b := returnParams();
t.Log(a,b);
}
可变参数:
package func_test
import "testing"
func Sum(ops ...int) int{
ret := 0
for _,op := range ops {
ret += op
}
return ret;
}
func TestSumParams(t *testing.T) {
t.Log(Sum(1,2,3))
t.Log(Sum(1,2,3,4,5))
}
defer延迟执行特性:
package func_test
import "testing"
import "fmt"
func Clear() {
fmt.Println("clear....");
}
func TestDeferFunc(t *testing.T) {
defer Clear()
fmt.Println("start");
}
1.数据的封装(结构体)
type Employee struct {
Id string
Name string
Age int
}
代码实例:
package struct_test
import (
"testing"
)
type Employee struct {
Id string
Name string
Age int
}
func TestNewObject(t *testing.T) {
e := Employee{"0","Bob",20}
e1 := Employee{Name:"Mike",Age:30}
e2 := new(Employee) // 返回指针
t.Log(e)
t.Log(e1)
t.Log(e2)
}
与其他主要编程语言的差异:
package struct_test
import (
"testing"
"fmt"
"unsafe"
)
func TestVarAddr(t *testing.T) {
e := Employee{"0","Bob",20}
fmt.Printf("Address is %x \n",unsafe.Pointer(&e.Name))
t.Log(e.getString());
}
//第一种定义方式在对应方法被调用时,实例的成员会进行赋值
func (e *Employee) getString() string {
return fmt.Sprintf("ID:%s-Name:%s-Age:%d",e.Id,e.Name,e.Age);
}
//通常情况下为了避免内存拷贝我们使用第二种方式定义
func (e *Employee) getAddrString() string {
return fmt.Sprintf("ID:%s-Name:%s-Age:%d",e.Id,e.Name,e.Age);
}
2.Go语言的接口与依赖
接口:与其他主要编程语言的差异
package interface_test
import (
"testing"
)
type params interface {
HelloWorld() string
}
type GoParams struct {
}
func (g *GoParams ) HelloWorld() string {
return "fmt.Println(\"Hello,world\")";
}
func TestClient(t *testing.T){
var p params
p = new(GoParams)
t.Log(p.HelloWorld());
}
3.扩展与复用
package extension_test
import (
"testing"
"fmt"
)
type Pet struct {
}
func (p *Pet) Speak() {
fmt.Println("...");
}
func (p *Pet) SpeakTo(host string) {
//p.Speak();
fmt.Println(" ",host)
}
type Dog struct {
Pet
}
func TestExtens(t *testing.T){
dog := new(Dog)
dog.GetDoger();
}
func (d *Dog) GetDoger() {
d.SpeakTo("host");
p := new(Pet);
p.SpeakTo("ssss");
}
4.空接口与断言
v,ok := p.(int)
package empty_interface
import (
"testing"
"fmt"
)
func DoSomething(p interface{}){
if i,ok := p.(int); ok {
fmt.Println("Intager",i);
return
}
if s,ok := p.(string); ok {
fmt.Println("String",s);
return
}
fmt.Println("Unknow Type")
}
func TestEmptyInterface(t *testing.T) {
DoSomething(10)
DoSomething("stark")
}
Go接口最佳实践:
倾向于使用小的接口定义,很多接口只包含一个方法。
type Reader interface {
Read(p []byte)(n int,err error)
}
type Writer interface {
Writer(p []byte)(n int,err error)
}
较大的接口定义,可以由多个小接口定义组合而成。
type ReadWrite interface {
Read(p []byte)(n int,err error)
Writer(p []byte)(n int,err error)
}
只依赖于必要功能的最小接口。
与其他主要编程语言的差异
type error interface {
Error() string
}
errors.New("n must be in the range [0,10]");
2.panic
3.recover
在不确定的情况下,可以重启来恢复程序
1.package
2.init方法
package
1.通过 go get 来获取远程依赖
依赖管理
1.协程
package groutine_test
import (
"fmt"
"time"
"testing"
)
func TestGroutine(t *testing.T) {
for i:= 0;i< 10;i++{
go func (i int) {
fmt.Println(i)
}(i)
time.Sleep(time.Millisecond * 50)
}
}
2.协程锁 sync.Mutex
3.CSP并发机制
Csp Vs Actor
package channel_test
import (
"testing"
"fmt"
"time"
)
func service () string {
time.Sleep(time.Millisecond * 50)
return "Deno"
}
func otherTask(){
fmt.Println("working on something else")
time.Sleep(time.Millisecond * 100)
fmt.Println("Task is done")
}
func TestService(t *testing.T) {
t.Log(service ())
otherTask()
}
Channel异步执行
package channel_test
import (
"testing"
"fmt"
"time"
)
func service () string {
time.Sleep(time.Millisecond * 50)
return "Deno"
}
func otherTask(){
fmt.Println("working on something else")
time.Sleep(time.Millisecond * 100)
fmt.Println("Task is done")
}
func AsynService() chan string {
retCh := make(chan string,1)
go func(){
ret := service()
fmt.Println("returned result")
retCh <- ret
fmt.Println("service exited")
}()
return retCh
}
func TestAsynService(t *testing.T) {
retCh := AsynService()
otherTask()
fmt.Println(<-retCh)
time.Sleep(time.Second * 1)
}
多路选择和超时
select {
case ret := <- retChannel
}
4.Channel的关闭和广播
sync.Pool 对象获取
sync.Pool 总结
1.单元测试
内置单元测试框架
-v:查看测试结果
-cover:测试代码覆盖率
go test -v -cover type_test.go
2.第三方 BDD框架
项目网站
https://github.com/smartystreets/goconvey
安装
go get -u github.com/smartystreets/goconvey
启动 web Ui
$GOPATH/bin/goconvey
reflect.TypeOf Vs reflect.ValueOf
Pipe-Filter模式
Micro Kernel
特点:
易于扩展、错误隔离、保持架构一致性
要点:
内置Json解析
type BasicInfo struct {
Name string `json:"name"`
Age int `json:"age"`
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。