Golang极简入门教程(一):基本概念

安装 Golang

http://golang.org/dl/ 可以下载到 Golang。安装文档:http://golang.org/doc/install

Hello Go

我们先创建一个文件 hello.go:

代码如下:

package main
 
import "fmt"
 
func main() {
    fmt.Printf("hello Golang\n");
}

执行此程序:

代码如下:

go run hello.go

Golang 程序由包(packages)组成,程序从 main 包开始运行:

代码如下:

package main

此语句表示此文件属于 main 包(多个源文件可以属于同一个包)。import 语句后接上包所在的路径(被叫做包路径或导入路径),一个目录中放置一个包,通常的做法是,目录名和包名相同:

代码如下:

import (
    "fmt"
    "math/rand"
)

这里的 “fmt” 和 “math/rand” 为包路径(导入路径)。上面的 import 语句也可以这样写:

代码如下:

import "fmt"
import "math/rand"

我们导入了包之后,就可以通过 “包名.name” 来引用导出的 name 了,例如:

代码如下:

import "fmt"
 
// fmt 包导出了 Printf
fmt.Printf("hello Golang\n");

在 Golang 中,一个名字如果首字母大写则表示此名字被导出。

函数

代码如下:

package main
 
import "fmt"
 
func add(x int, y int) int {
    return x + y
}
 
func main() {
    fmt.Println(add(42, 13))
}

需要注意的就是,变量名在类型之前,这和很多语言都不一样。另外 x int, y int 也可以写为 x, y int:

代码如下:

func add(x, y int) int {
    return x + y
}

函数可以返回多个值:

代码如下:

package main
 
import "fmt"
 
func swap(x, y string) (string, string) {
    return y, x
}
 
func main() {
    a, b := swap("hello", "world")
    fmt.Println(a, b)
}

返回值可以被指定变量名,并且像变量一样使用:

代码如下:

package main
 
import "fmt"
 
func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}
 
func main() {
    fmt.Println(split(17))
}

可以看到 split 函数直接使用 return 语句而不用带参数。

变量

变量的声明使用 var 语句:

代码如下:

var i int
var c, python, java bool

变量在声明时可以进行初始化:

代码如下:

var x, y int = 1, 2
var i, j = true, "hello"

我们看到,初始化时可以指定也可以不指定变量类型。
按照 Golang 的语法,在函数外的任何结构(construct)都通过一个关键字开始,例如变量使用 var 关键字开始,函数使用 func 关键字开始。在函数内,变量赋值可以使用 := 操作符:

代码如下:

package main
 
func main() {
    var x, y int = 1, 2
    i, j := true, "hello"
}

:= 操作符左边为变量,右边为值。

数据类型

基本数据类型:

1.bool
2.string
3.int int8 int16 int32 int64
4.uint uint8 uint16 uint32 uint64
5.uintptr
6.byte(等价于 uint8)
7.rune(等价于 int32,用于表示一个 unicode code point)
8.float32 float64
9.complex64 complex128

类型转换使用表达式 T(v),含义为将 v 转换为类型 T:

代码如下:

var i int = 42
var f float64 = float64(i)
 
i := 42
f := float64(i)

类型转换总需要显式的进行。

使用 const 来声明常量:

代码如下:

const Pi = 3.14
 
const (
    Big = 1 << 100
    Small = Big >> 99
)

控制语句

for 语句

Golang 使用(且只使用)for 来进行循环(没有 while 语句):

代码如下:

package main
 
func main() {
    sum := 0
   
    for i := 0; i < 10; i++ {
        sum += i
    }
   
    // 这种写法等价于 C/C++ 等语言中的 while 语句
    for sum < 1000 {
        sum += sum
    }
}

区别于 C/C++ 等语言,使用 for 语句时不需要 () 并且 {} 是必须的(后面谈到的 if、switch 在此语法处理上也是一样的)。如果需要无限循环,那么使用:

代码如下:

for {
}

if 语句

if 语句可以在执行条件判断前带一个语句(这常被叫做 if 带上一个短语句),此语句中变量的生命周期在 if 语句结束后结束。例如:

代码如下:

package main
 
import (
    "fmt"
    "math/rand"
)
 
func main() {
    if n := rand.Intn(6); n <= 2 {
        fmt.Println("[0, 2]", n)
    } else {
        fmt.Println("[3, 5]", n)
    }
 
    // 这里开始无法使用变量 n
}

switch

代码如下:

package main
 
import (
    "fmt"
    "runtime"
)
 
func main() {
    fmt.Print("Go runs on ")
    // switch 类似 if 可以带上一个短语句
    switch os := runtime.GOOS; os {
    case "darwin":
        fmt.Println("OS X.")
    case "linux":
        fmt.Println("Linux.")
    default:
        // freebsd, openbsd,
        // plan9, windows...
        fmt.Printf("%s.", os)
    }
}

不像 C/C++ 等语言,Golang 中无需使用 break 语句来跳出 switch。另外,switch 可以没有条件:

代码如下:

package main
 
import (
    "fmt"
    "time"
)
 
func main() {
    t := time.Now()
    switch {
    case t.Hour() < 12:
        fmt.Println("Good morning!")
    case t.Hour() < 17:
        fmt.Println("Good afternoon.")
    default:
        fmt.Println("Good evening.")
    }
}

defer

一个 defer 语句能够将一个函数调用加入一个列表中(这个函数调用被叫做 deferred 函数调用),在当前函数调用结束时调用列表中的函数。范例:

代码如下:

func CopyFile(dstName, srcName string) (written int64, err error) {
    src, err := os.Open(srcName)
    if err != nil {
        return
    }
    defer src.Close()
 
    dst, err := os.Create(dstName)
    if err != nil {
        return
    }
    defer dst.Close()
 
    return io.Copy(dst, src)
}

deferred 函数调用按先进后出的顺序执行:

代码如下:

package main
 
import "fmt"
 
func main() {
    for i := 0; i < 5; i++ {
        // 输出 43210
        defer fmt.Print(i)
    }
}

结构(structs)

结构是一个域的集合:

代码如下:

package main
 
import "fmt"
 
type Vertex struct {
    X int
    Y int
}
 
func main() {
    v := Vertex{1, 2}
    v.X = 4
    fmt.Println(v)
}

Golang 中是存在指针的,但是指针不支持算术运算:

代码如下:

p := Vertex{1, 2} // {1, 2} 为 struct literal
q := &p // q 类型为 *Vertex
q.X = 2 // 直接访问域 X

就像上面看到的,struct 的 literal 由 {} 包裹,在 struct literal 中我们可以使用 Name: 这样的语法来为特定域设置值:

代码如下:

type Vertex struct {
    X, Y int
}
 
r := Vertex{X: 3} // 这时候 Y 为 0

new 函数

我们可以通过表达式 new(T) 分配一个被初始化为 0 且类型为 T 的值,并且返回指向此值的指针,用法如下:

代码如下:

var p *T = new(T)
p := new(T)

更详尽的例子:

代码如下:

package main
 
import "fmt"
 
type Vertex struct {
    X, Y int
}
 
func main() {
    v := new(Vertex)
    fmt.Println(v)
    v.X, v.Y = 11, 9
    fmt.Println(v)
}

数组和 slice

[n]T 在 Golang 中是一个类型(就像 *T 一样),表示一个长度为 n 的数组其元素类型为 T。范例:

代码如下:

package main
 
import "fmt"
 
func main() {
    var a [2]string
    a[0] = "Hello"
    a[1] = "World"
    fmt.Println(a[0], a[1])
    fmt.Println(a)
}

注意,数组长度无法被改变。

slice 是一个数据结构,其指向一个数组某个连续的部分。slice 用起来很像数组。[]T 为 slice 类型,其中元素类型为 T:

代码如下:

package main
 
import "fmt"
 
func main() {
    // 构建一个 slice
    p := []int{2, 3, 5, 7, 11, 13}
    fmt.Println("p ==", p)
 
    for i := 0; i < len(p); i++ {
        fmt.Printf("p[%d] == %d\n", i, p[i])
    }
}

表达式 s[lo:hi] 用于创建一个 slice,新创建的 slice 的元素为 s 中 [lo, hi) 位置的元素。

创建 slice 使用 make 函数(而不是用 new 函数,因为需要设置额外的参数来控制 slice 的创建):

代码如下:

// len(a) 为 5
a := make([]int, 5)

这里 make 函数会创建一个数组(其元素初始化为 0)并返回一个 slice 指向此数组。make 可以带第三个参数,用于指定容量:

代码如下:

// len(b) 为 0
// cap(b) 为 5
b := make([]int, 0, 5)
 
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4

一个没有值的 slice 是 nil,长度和容量都为 0。

代码如下:

package main
 
import "fmt"
 
func main() {
    var z []int
    fmt.Println(z, len(z), cap(z))
    if z == nil {
        fmt.Println("nil!")
    }
}

range

range 被用在 for 中来迭代一个 slice 或者一个 map:

代码如下:

package main
 
import "fmt"
 
var s = []int{1, 2, 3}
 
func main() {
    for i, v := range s {
        fmt.Println(i, v)
    }
 
    // 只需要值,使用 _ 忽略索引
    for _, v := range s {
        fmt.Println(v)
    }
 
    // 只需要索引
    for i := range s {
        fmt.Println(i)
    }
}

map

map 用于映射 key 到 value(值)。map 可以通过 make 来创建(而非 new):

代码如下:

package main
 
import "fmt"
 
type Vertex struct {
    Lat, Long float64
}
 
var m map[string]Vertex
 
func main() {
    m = make(map[string]Vertex)
    m["Bell Labs"] = Vertex{
        40.68433, -74.39967,
    }
    fmt.Println(m["Bell Labs"])
}

map iteral 很像 struct literal:

代码如下:

var m = map[string]Vertex{
    // 这里 Vertex 可以省略不写
    "Bell Labs": Vertex{
        40.68433, -74.39967,
    },
    "Google": Vertex{
        37.42202, -122.08408,
    },
}

使用 [] 来访问 map 中的值,使用 delete 来删除 map 中的值:

代码如下:

m[key] = elem
elem = m[key]
delete(m, key)

如果需要检查 map 中某 key 是否存在使用:

代码如下:

elem, ok = m[key]

elem 表示 key 的值(key 不存在时,elem 为 0),ok 表示 key 是否存在。

闭包

Golang 中函数也是一个值(就像 int 值一样),且函数可以是一个闭包。闭包是一个引用了外部变量的函数。看一个例子:

代码如下:

package main
 
import "fmt"
 
func adder() func(int) int {
    sum := 0
    // 返回一个闭包,此闭包引用了外部变量 sum
    return func(x int) int {
        sum += x
        return sum
    }
}
 
func main() {
    a := adder()
    fmt.Println(a(9527))
}

时间: 2014-10-26

我放弃Python转Go语言的9大理由(附优秀书籍推荐)

前言 Go大概2009年面世以来,已经8年了,也算是8年抗战.在这8年中,已经有很多公司开始使用Go语言开发自己的服务,甚至完全转向Go开发,也诞生了很多基于Go的服务和应用,比如Dokcer.k8s等,很多的大公司也在用,比如google(作为开发Go语言的公司,当仁不让).Facebook.腾讯.百度.阿里.京东.小米以及360,当然除了以上提到的,还有很多公司也都开始尝试Golang,这其中是什么原因呢?让我们来一起分析分析. 原因 1:性能 Go 极其地快.其性能与 Java 或 C++

Golang极简入门教程(四):编写第一个项目

workspace Golang 的代码必须放置在一个 workspace 中.一个 workspace 是一个目录,此目录中包含几个子目录: 1.src 目录.包含源文件,源文件被组织为包(一个目录一个包) 2.pkg 目录.包含包对象(package objects) 3.bin 目录.包含可执行的命令 包源文件(package source)被编译为包对象(package object),命令源文件(command source)被编译为可执行命令(command executable).

Python书单 不将就

每天都有小伙伴询问Python的书,哎呀,动力所致,书单来了.7本,涵盖范围蛮大的.Python热持续中,入门计算机首选语言. python游戏编程快速上手 (斯维加特著) (点击,直接下载) 本书可以帮助读者在轻松有趣的过程中,掌握Python游戏编程的基本技能.本书适合不同年龄和层次的Python编程初学者阅读. 像计算机科学家一样思考Python (点击,直接下载) 全书共19章和3个附录,详细介绍了Python语言编程的方方面面.<像计算机科学家一样思考Python>是一本实用的学习指

不可错过的十本Python好书

以往的文章中小编已经给大家陆续推荐了很多的Python书籍,可以说品种齐全.本本经典了,不知道你是不是已经眼花缭乱,不知道该选择哪本好了呢?今天我来为大家分享十本不可错过的Python好书,分别适合入门.进阶到精深三个不同阶段的人来阅读. Python高性能编程 Amazon 五星畅销书. Python 入门进阶必读. Python代码仅仅能够正确运行还不够,你需要让它运行得更快. Python核心编程(第3版) (点击图书,可直接下载) 系列销量逾70000册. Python高手进阶图书,详解

Mac OS系统安装golang教程

下载golang安装包 下载地址: http://www.golangtc.com/download https://code.google.com/p/go/downloads/list go1.4.darwin-amd64-osx10.8.pkg  go1.4 Mac OS X (x86 64-bit) PKG installer 设置环境变量 配置 GOROOT 和 GOPATH: 复制代码 代码如下: 创建目录下的go文件夹: mkdir ~/go 下面的东西放到.bash_rc(也可能

GO语言(golang)基础知识

今天说一些golang的基础知识,还有你们学习会遇到的问题,先讲解hello word 复制代码 代码如下: package main import "fmt" func main() {    fmt.Println("你好,我们"); } package name 包机制,每一个独立的go程序都需要有一个package main的申明,主要是要为下边入口函数main()做申明的,import和java一样导入包用的 就是下边我们函数用的fmt.Println()

易语言编程基础知识

创建一个易应用程序只需要短短几分钟的时间 - 通过在设计窗口上"绘制"诸如编辑框和按钮等组件来创建用户界面.然后,为窗口和组件设置属性以规定诸如标题.位置.尺寸等的值.最后,编写处理程序将生命真正赋于程序. 组件及事件驱动 组件及其事件驱动是使用易语言在 Windows 环境下编程的基础知识.所谓"组件",即用作组成用户图形界面的基本成员,譬如:窗口.编辑框.图片框等等.组件按可否容纳其它组件划分为容器类和非容器类.按运行时是否可能具有可视外形划分为界面类和功能类.

WAP建站WML语言语法基础教程第1/6页

完成WAP服务器的建立和WAP浏览器的安装之后,我们接下来就可以使用WML语言来编写WAP网页或应用,并通过WAP服务器及浏览器进行调试.从本章开始我们将系统地学习WML语言,本章主要讲解WML语言的基础知识,下一章全面讲解WML的语法.标签和规则. 2.1 WML的简单例子及编辑.测试方法 无限标记语言WML(Wireless Markup Language)是一种基于扩展标记语言XML(Extension Markup Language)的语言,是XML的子集.它可以显示各种文字.图像等数据

IOS开发之路--C语言基础知识

概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift 这么看下去还有大量的内容需要持续补充,但是今天我们从最基础的C语言开始,C语言部分我将分成几个章节去说,今天我们简单看一下C的一些基础知识,更高级的内容我将放到后面的文章中. 今天基础知识分为以下几点内容(注意:循环.条件语句在此不再赘述): Hello World 运行过程 数据类型 运算符 常用

c语言 树的基础知识(必看篇)

第一.树的定义: 1.有且只有一个称为根的节点 2.有若干个互不相交的子树,这些子树本身也是一颗树 第二.专业术语: 树的深度:从根节点到最低层,节点的层数 ,称之为树的深度.  根节点是第一层 结点的层次:根节点为第一层,根节点的子节点为第2层,以此类推 叶子节点:没有子节点的节点 非终端节点:实际就是非叶子节点 结点度: 子节点的个数称为度树的度 第三.树的分类 一般树:任意一个节点的子节点的个数不受限制 二叉树:任意一个节点的子节点最多2个,且子节点的位置不可更改 满二叉树:在不增加层数的

图文详解C语言位运算基础知识

C语言位运算基础知识分享给大家,希望对大家有帮助. 1.   程序中的所有数在计算机内存中都是以二进制的形式储存的.位运算说穿了,就是直接对整数在内存中的二进制位进行操作. 2.  与运算:只有前后两个运算数都是 1 的时候结果才是1. 3.  或运算:有1位为1,结果便为1. 4.  异或:不相同则为1. 5.  取反运算:将1变为0,将0变为1. 6.  移位运算:左移则乘2,右移则除2.如果超出边界,则舍弃. 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们.

PHP小白必须要知道的php基础知识(超实用)

很多人看到PHP就以为是程序员,就以为钱很多(虽然是事实),但是也要考虑下自己是不是适合这一行,知道PHP是什么吗?PHP都有什么样的功能,都能用来干嘛? PHP是什么? •PHP(PHP: Hypertext Preprocessor,超文本预处理器的缩写),是一 种被广泛应用的开放源代码的.基于服务器端的用于产生动态网页 的.可嵌入HTML中的脚本程序语言,尤其适合 WEB 开发. •当客户端向服务器的程序提出请求时,web服务器根据请求晌应对应 的页面,当页面中含有php脚本时,服务器会交

学习shell脚本之前的基础知识[图文]

日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写shell脚本,那么你就不算一个合格的管理员.目前很多单位在招聘linux系统管理员时,shell脚本的编写是必考的项目.有的单位甚至用shell脚本的编写能力来衡量这个linux系统管理员的经验是否丰富.笔者讲这些的目的只有一个,那就是让你认真对待shell脚本,从一开始就要把基础知识掌握牢固,然后要不断的练习,只要你shell脚本写的好,相信你的linux求职路就会轻松的多.笔者在这一章中并不会多么详细的介绍shell脚本

HTTP报文及ajax基础知识

HTTP报文 客户端传递给服务器的内容 和 服务器传递给客户端的内容 都属于HTTP报文 起始行:请求起始行  响应起始行 首部:请求首部 响应首部 通用首部(请求和响应都有的) 自定义首部 主体:请求主体  响应主体 客户端传递给服务器端数据: 请求URL后面问号传参的方式传递给服务器  /getList?name=zhangsan&age=7 设置请求的首部(设置请求头信息) 设置请求主体,把传递给服务器的内容放在请求主体中传递给服务器 服务器端传递给客户端数据: 设置响应头信息 设置响应主

Lua中函数与面向对象编程的基础知识整理

函数 1. 基础知识 调用函数都需要写圆括号,即使没有参数,但有一种特殊例外:函数若只有一个参数且参数是字面字符串或table构造式,则圆括号可有可无,如dofile 'a.lua',f{x=10, y=20}. Lua为面向对象式的调用提供冒号操作符的特殊语法,如o.foo(o, x)等价于o:foo(x).和Javascript类似,调用函数时提供的实参数量可以与形参数量不同,若实参多了则舍弃,不足则多余的形参初始化为nil. 1.1 多重返回值 Lua允许函数返回多个结果,函数返回如ret