从例子中学习 go 语言 —— 基本语法
2013-06-03 13:19
781 查看
go 语言或是 golang 官网上有个 tour。从例子中学习一门语言虽然具有片面性,但是往往是一个入门的好方法;如果一开始就去是看手册的话,有些凌乱,摸不着头脑,有点看字典的味道。所以,先从例子中学习,然后再系统的学习,应该是个不错的方法。
本篇文章基本按照 tour 的步骤,跑跑例子,从例子中去猜测/分析 go 的语法以及结构等,一定程度上可以锻炼一下,观察和分析能力。
hello,world:
package main
import "fmt"
func main() {
fmt.Println("hello,world")
// 输出 hello,world
}
1). package 将程序打包;
2). import 导入其他包,包名用双引号引住;fmt 包 —— 应该是 format 格式化输入/输出的包;
3). func 声明函数,main 函数,不带参数,不返回值,函数体用 { } 括号括住;左大括号 { 与声明在同一行(必须!);
4). fmt.Println 向控制台输出,包名小写,函数名首字母大写;
5). 语句不带分号; // 试验发现,分号可有可无;实际上 go 是自动插入分号;
6). package 必须写在前面;必须先 import 包,然后才能使用包中的东西;
7). // 行注释,/* */ 块注释,都是常用的方法;
导入多个包:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Happy", math.Pi, "Day")
}
1). import 导入多个包的简单写法;小括号括住,包名换行写;或是用分号将它们隔开;
2). 新的包 math,应该是数学包;
3). math.Pi 圆周率;// 小数点后有十五位 math.Pi == 3.141592653589793;math.E == 2.718281828459045;
4). fmt.Println 多个参数多个输出,从左到有一一输出;
5). 程序从 main 包的 main 函数开始执行;
格式化输出:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Printf("Now
you have %g problems.",
math.Nextafter(2, 3))
}
1). 一条语句可以换行写,不过是在逗号处隔开;
2). fmt.Printf 格式化输出函数,类似于 c 语言的 printf ,第一参数是格式化字符串;函数输出不自动换行;
3). fmt.Printf 名字类似于 fmt.Println;包的名字一般小写;包中的函数 Printf/Println 和 值 Pi/E 首字母看来是大写;
4). math.Nextafter 方法,暂时不纠结到底什么意思;// Nextafter(2,2) == 2;Nextafter(2,3) == 2.0000000000000004;Nextafter(2,1) == 1.9999999999999998
函数定义和使用:
package main
import "fmt"
func add(x int, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
1). func 进行函数声明,func 函数名(参数列表) 返回值类型;参数以及返回值的类型向后写,而不是像 c、c++ 和 Java 等写在前面;
2). 函数调用都一样,函数名后面跟上参数,参数之间逗号隔开,小括号括住;
3). int 是整数类型,两个 int 相加,结果是 int;貌似是废话;
函数声明时类型省略:
package main
import "fmt"
func add(x, y int, z int) int {
return x + y + z
}
func main() {
fmt.Println(add(42, 13, 12))
}
1). 这里 x 类型么有指定,认为和后面的 y 的类型一致;因为 x、y、z 都是 int 型,所以实际上可以只留 z 的 int 就可以,y 的也可以省略;
2). 省略了认为是和后面的重复,也就是只有类型重复的时候,偶们才可以省略;
函数多返回值的用法:
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
// var a, b := swap("hello", "world")
fmt.Println(a, b) //
world hello
}
1). c 类的语言(c/c++/java等) 一般函数只有一个返回值,如果想返回多个,一般都要进行封装称结构体或是类,F# 引入元组类型,就是简单的用小括号一括,就可以把若干个值放在一块;这里的用法是类似的,函数返回值用括号一括就表明一下子返回多个值,简单易用;
2). 至此,貌似都嚒见过怎么声明变量,只是用了函数中的变量以及将函数返回值简单返回;这个例子中有两种声明方法,一种不需要借助 var关键字进行隐式声明,一种需要算式显式声明——明白滴告诉你这就是个变量 variable,至于类型,看后面;
3). 如此交换两个变量甚好,以前见过的交换,一般都需要借助于辅助变量或是其他运算;
声明函数的返回值,不仅仅是类型:
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4/9
y = sum - x
return
}
func main() {
fmt.Println(split(36))
// fmt.Println(split(17))
}
1). 看函数声明,直接把返回值 x、y声明出来了,函数内部可以直接使用参数和返回值变量,而且 return 不需要显式地返回 x、y;
2). 声明的返回值变量,不赋值就用的话,默认值是 0 或是 false 等;
3). 可能你奇怪,如果 return x+2,y+2 会怎么样,实际上是将 x、y 各加 2 的结果返回,不报警告也不报错;也就是所如果有 return 值那就是返回值,没有的话,才将声明的返回值返回;
4). int * int 结果是 int ; int / int 结果也是 int,不是浮点数 —— 这也是 c 语言的一贯传统;
变量声明:
package main
import "fmt"
var x, y, z int
var c, python, java bool
func main() {
fmt.Println(x, y, z, c, python, java)
}
1). 用 var 进行变量声明,和函数声明时参数的声明一样,类型向后写,也就是先写变量名,再写类型;
2). 多个变量类型一样的话,可以合在一起写;int 和 bool 是目前见过的整数和布尔类型;
3). 声明变量如果么有显式的初始化,都有默认值,int 为 0,bool 为 false ;
4). 没有初始化的变量声明,类型不同不能连在一起写;
变量声明和类型推断:
package main
import "fmt"
var x, y, z int = 1, 2, 3
var c, python, java = true, false, "no!"
func main() {
fmt.Println(x, y, z, c, python, java)
}
1). 变量声明的同时可以初始化;
2). 如果有初始化的话,变量类型可以不写,类型靠推断而得;
3). 变量声明可以连着写;
4). "hello"、"yes" 这是 string —— 字符串类型;
两种变量声明方法:
package main
import "fmt"
func main() {
var x, y, z int = 1, 2, 3
c, python, java := true, false, "no!"
fmt.Println(x, y, z, c, python, java)
}
1). 隐式变量声明和显式变量声明,也就是不使用和使用 var 关键字,同时两种运算符也不相同;
2). 函数外不能使用隐式变量声明,也就是 a : = 3 这种;
常量声明:
package main
import "fmt"
const Pi = 3.14
func main() {
const World = "世界"
fmt.Println("Hello", World)
fmt.Println("Happy", Pi, "Day")
const Truth = true
fmt.Println("Go
rules?", Truth)
}
1). const 用来声明常量,const 浮点数、const 整数、const 字符串、const 布尔值;
接触浮点数 / 实数:
package main
import "fmt"
func add(x int, y float64) int {
return x + int(y)
}
func main() {
fmt.Println(add(42, 13))
}
1). float64 是 64 位的浮点数,还有 float32;总之现在简单滴看,就是 —— 实数 或是 小数;
2). int + float64 不合法,也就是 int 不能直接和 float64 相加;
3). int(y) 将 y 转化为 int 值;
4). 函数传参数的时候,可以将 int 传给 float64;
大整数常量以及浮点数:
package main
import "fmt"
const (
Big = 1<<100
Small = Big>>99 //
2
)
func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
return x*0.1
}
func main() {
// fmt.Println(Big) // overflow int
fmt.Println(float64(Big))
fmt.Println(Small)
// 2
fmt.Println(needInt(Small))
// 21
fmt.Println(needFloat(Small)) //
0.2
fmt.Println(needFloat(Big))
}
1). 声明多个 const 可以简写;小括号括起来,然后换行写,和 import 包类似;
2). 参数传递,可以将 int 传给 float64;
3). int 有表示范围一说,数值太大,会溢出;
for 循环结构:
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
1). 相对于 c 的 for 循环结构来说,去掉了两侧的小括号;
for 循环结构简化版:
package main
import "fmt"
func main() {
sum := 1
for ; sum < 1000; {
sum += sum
}
fmt.Println(sum)
}
1). for 去掉了前置和后置语句,但是分号还在;
for 循环结构再次简化:
package main
import "fmt"
func main() {
sum := 1
//for ; sum < 1000; {
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
1). for 去掉了前置和后置语句,但是分号还在;
2). for 去掉了前置和后置语句,分号也可以去掉,这样就相当于 c 的while 结构;
死循环结构:
package main
func main() {
for ; ; {
//for {
}
}
1). for 没有判断条件,默认为 true,也就是死循环;
2). for 没有判断条件,也没有前置和后置语句,去掉所有的分号,就有了 for 的最简化形式;
if 选择结构:
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func main() {
fmt.Println(sqrt(2), sqrt(-4))
}
1). if 选择结构,相对于 c 来说,去掉了两边的小括号;
2). math.Sqrt 求实数的平方根;
3). 递归调用啊,有木有! sqrt 函数!
3). 将 float64 值字符串化的方法 fmt.Sprint;Sprint 名字类似于 Print/Println/Printf/Fprintf ,可以略猜出来,S 应该是 string 的意思;
if 选择结构加强版:
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v
< lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
1). if 选择结构可以加前置语句,类似于 for ;如果嚒有前置语句为空,可以留下分号,也可以去掉分号;
2). 前置语句引入的变量的作用域仅限于 if 结构;
3). math.Pow 求幂指数;
if - else 选择结构
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v
< lim {
return v
} else {
fmt.Printf("%g
>= %g\n", v, lim)
}
// can't use v here, though
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
1). if - else 结构
2). if 前置语句引入的变量作用域也可以用于 else ;
3). 这个运行结果有些比较奇怪!
复数运算:
package main
import (
"math/cmplx"
"fmt"
)
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmplx.Sqrt(-5+12i)
)
func main() {
const f = "%T(%v)\n"
fmt.Printf(f, ToBe, ToBe)
fmt.Printf(f, MaxInt, MaxInt)
fmt.Printf(f, z, z)
}
1). go 内置复数运算,使用 math/cmplx 包;
2). const 常量字符串可以用于 fmt.Printf 的第一个参数,见过的格式化有 %T %v %g 几种;
3). 换行符,都熟悉的;
4). math/cmplex 复数包;cmplx.Sqrt 复数开根号
5). go 的基本类型:
本篇文章基本按照 tour 的步骤,跑跑例子,从例子中去猜测/分析 go 的语法以及结构等,一定程度上可以锻炼一下,观察和分析能力。
hello,world:
package main
import "fmt"
func main() {
fmt.Println("hello,world")
// 输出 hello,world
}
1). package 将程序打包;
2). import 导入其他包,包名用双引号引住;fmt 包 —— 应该是 format 格式化输入/输出的包;
3). func 声明函数,main 函数,不带参数,不返回值,函数体用 { } 括号括住;左大括号 { 与声明在同一行(必须!);
4). fmt.Println 向控制台输出,包名小写,函数名首字母大写;
5). 语句不带分号; // 试验发现,分号可有可无;实际上 go 是自动插入分号;
6). package 必须写在前面;必须先 import 包,然后才能使用包中的东西;
7). // 行注释,/* */ 块注释,都是常用的方法;
导入多个包:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Happy", math.Pi, "Day")
}
1). import 导入多个包的简单写法;小括号括住,包名换行写;或是用分号将它们隔开;
2). 新的包 math,应该是数学包;
3). math.Pi 圆周率;// 小数点后有十五位 math.Pi == 3.141592653589793;math.E == 2.718281828459045;
4). fmt.Println 多个参数多个输出,从左到有一一输出;
5). 程序从 main 包的 main 函数开始执行;
格式化输出:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Printf("Now
you have %g problems.",
math.Nextafter(2, 3))
}
1). 一条语句可以换行写,不过是在逗号处隔开;
2). fmt.Printf 格式化输出函数,类似于 c 语言的 printf ,第一参数是格式化字符串;函数输出不自动换行;
3). fmt.Printf 名字类似于 fmt.Println;包的名字一般小写;包中的函数 Printf/Println 和 值 Pi/E 首字母看来是大写;
4). math.Nextafter 方法,暂时不纠结到底什么意思;// Nextafter(2,2) == 2;Nextafter(2,3) == 2.0000000000000004;Nextafter(2,1) == 1.9999999999999998
函数定义和使用:
package main
import "fmt"
func add(x int, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
1). func 进行函数声明,func 函数名(参数列表) 返回值类型;参数以及返回值的类型向后写,而不是像 c、c++ 和 Java 等写在前面;
2). 函数调用都一样,函数名后面跟上参数,参数之间逗号隔开,小括号括住;
3). int 是整数类型,两个 int 相加,结果是 int;貌似是废话;
函数声明时类型省略:
package main
import "fmt"
func add(x, y int, z int) int {
return x + y + z
}
func main() {
fmt.Println(add(42, 13, 12))
}
1). 这里 x 类型么有指定,认为和后面的 y 的类型一致;因为 x、y、z 都是 int 型,所以实际上可以只留 z 的 int 就可以,y 的也可以省略;
2). 省略了认为是和后面的重复,也就是只有类型重复的时候,偶们才可以省略;
函数多返回值的用法:
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
// var a, b := swap("hello", "world")
fmt.Println(a, b) //
world hello
}
1). c 类的语言(c/c++/java等) 一般函数只有一个返回值,如果想返回多个,一般都要进行封装称结构体或是类,F# 引入元组类型,就是简单的用小括号一括,就可以把若干个值放在一块;这里的用法是类似的,函数返回值用括号一括就表明一下子返回多个值,简单易用;
2). 至此,貌似都嚒见过怎么声明变量,只是用了函数中的变量以及将函数返回值简单返回;这个例子中有两种声明方法,一种不需要借助 var关键字进行隐式声明,一种需要算式显式声明——明白滴告诉你这就是个变量 variable,至于类型,看后面;
3). 如此交换两个变量甚好,以前见过的交换,一般都需要借助于辅助变量或是其他运算;
声明函数的返回值,不仅仅是类型:
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4/9
y = sum - x
return
}
func main() {
fmt.Println(split(36))
// fmt.Println(split(17))
}
1). 看函数声明,直接把返回值 x、y声明出来了,函数内部可以直接使用参数和返回值变量,而且 return 不需要显式地返回 x、y;
2). 声明的返回值变量,不赋值就用的话,默认值是 0 或是 false 等;
3). 可能你奇怪,如果 return x+2,y+2 会怎么样,实际上是将 x、y 各加 2 的结果返回,不报警告也不报错;也就是所如果有 return 值那就是返回值,没有的话,才将声明的返回值返回;
4). int * int 结果是 int ; int / int 结果也是 int,不是浮点数 —— 这也是 c 语言的一贯传统;
变量声明:
package main
import "fmt"
var x, y, z int
var c, python, java bool
func main() {
fmt.Println(x, y, z, c, python, java)
}
1). 用 var 进行变量声明,和函数声明时参数的声明一样,类型向后写,也就是先写变量名,再写类型;
2). 多个变量类型一样的话,可以合在一起写;int 和 bool 是目前见过的整数和布尔类型;
3). 声明变量如果么有显式的初始化,都有默认值,int 为 0,bool 为 false ;
4). 没有初始化的变量声明,类型不同不能连在一起写;
变量声明和类型推断:
package main
import "fmt"
var x, y, z int = 1, 2, 3
var c, python, java = true, false, "no!"
func main() {
fmt.Println(x, y, z, c, python, java)
}
1). 变量声明的同时可以初始化;
2). 如果有初始化的话,变量类型可以不写,类型靠推断而得;
3). 变量声明可以连着写;
4). "hello"、"yes" 这是 string —— 字符串类型;
两种变量声明方法:
package main
import "fmt"
func main() {
var x, y, z int = 1, 2, 3
c, python, java := true, false, "no!"
fmt.Println(x, y, z, c, python, java)
}
1). 隐式变量声明和显式变量声明,也就是不使用和使用 var 关键字,同时两种运算符也不相同;
2). 函数外不能使用隐式变量声明,也就是 a : = 3 这种;
常量声明:
package main
import "fmt"
const Pi = 3.14
func main() {
const World = "世界"
fmt.Println("Hello", World)
fmt.Println("Happy", Pi, "Day")
const Truth = true
fmt.Println("Go
rules?", Truth)
}
1). const 用来声明常量,const 浮点数、const 整数、const 字符串、const 布尔值;
接触浮点数 / 实数:
package main
import "fmt"
func add(x int, y float64) int {
return x + int(y)
}
func main() {
fmt.Println(add(42, 13))
}
1). float64 是 64 位的浮点数,还有 float32;总之现在简单滴看,就是 —— 实数 或是 小数;
2). int + float64 不合法,也就是 int 不能直接和 float64 相加;
3). int(y) 将 y 转化为 int 值;
4). 函数传参数的时候,可以将 int 传给 float64;
大整数常量以及浮点数:
package main
import "fmt"
const (
Big = 1<<100
Small = Big>>99 //
2
)
func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
return x*0.1
}
func main() {
// fmt.Println(Big) // overflow int
fmt.Println(float64(Big))
fmt.Println(Small)
// 2
fmt.Println(needInt(Small))
// 21
fmt.Println(needFloat(Small)) //
0.2
fmt.Println(needFloat(Big))
}
1). 声明多个 const 可以简写;小括号括起来,然后换行写,和 import 包类似;
2). 参数传递,可以将 int 传给 float64;
3). int 有表示范围一说,数值太大,会溢出;
for 循环结构:
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
1). 相对于 c 的 for 循环结构来说,去掉了两侧的小括号;
for 循环结构简化版:
package main
import "fmt"
func main() {
sum := 1
for ; sum < 1000; {
sum += sum
}
fmt.Println(sum)
}
1). for 去掉了前置和后置语句,但是分号还在;
for 循环结构再次简化:
package main
import "fmt"
func main() {
sum := 1
//for ; sum < 1000; {
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
1). for 去掉了前置和后置语句,但是分号还在;
2). for 去掉了前置和后置语句,分号也可以去掉,这样就相当于 c 的while 结构;
死循环结构:
package main
func main() {
for ; ; {
//for {
}
}
1). for 没有判断条件,默认为 true,也就是死循环;
2). for 没有判断条件,也没有前置和后置语句,去掉所有的分号,就有了 for 的最简化形式;
if 选择结构:
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func main() {
fmt.Println(sqrt(2), sqrt(-4))
}
1). if 选择结构,相对于 c 来说,去掉了两边的小括号;
2). math.Sqrt 求实数的平方根;
3). 递归调用啊,有木有! sqrt 函数!
3). 将 float64 值字符串化的方法 fmt.Sprint;Sprint 名字类似于 Print/Println/Printf/Fprintf ,可以略猜出来,S 应该是 string 的意思;
if 选择结构加强版:
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v
< lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
1). if 选择结构可以加前置语句,类似于 for ;如果嚒有前置语句为空,可以留下分号,也可以去掉分号;
2). 前置语句引入的变量的作用域仅限于 if 结构;
3). math.Pow 求幂指数;
if - else 选择结构
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v
< lim {
return v
} else {
fmt.Printf("%g
>= %g\n", v, lim)
}
// can't use v here, though
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
1). if - else 结构
2). if 前置语句引入的变量作用域也可以用于 else ;
3). 这个运行结果有些比较奇怪!
复数运算:
package main
import (
"math/cmplx"
"fmt"
)
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmplx.Sqrt(-5+12i)
)
func main() {
const f = "%T(%v)\n"
fmt.Printf(f, ToBe, ToBe)
fmt.Printf(f, MaxInt, MaxInt)
fmt.Printf(f, z, z)
}
1). go 内置复数运算,使用 math/cmplx 包;
2). const 常量字符串可以用于 fmt.Printf 的第一个参数,见过的格式化有 %T %v %g 几种;
3). 换行符,都熟悉的;
4). math/cmplex 复数包;cmplx.Sqrt 复数开根号
5). go 的基本类型:
bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr byte // uint8 rune // int32 float32 float64 complex64 complex128
原文地址:http://ilovers.sinaapp.com/drupal/node/32
本系列的博客为本人学习收藏
相关文章推荐
- OC语言学习22-Block基本语法
- Kotlin开发语言学习(2)基本语法
- 【1】Groovy语言学习:groovy语言简介及基本语法
- Go语言的风雨历程-----基本的语法
- c++、c#、Python、GO语言基本语法比较
- go基本语法学习笔记之类型
- go语言学习-golang的基本数据类型
- PHP-Manual的学习----【语言参考】----【基本语法】
- 【Python学习系列六】Python语言基本语法
- 【Go学习】浅析Go语言Interface类型的语法行为及用法
- Golang学习笔记(2)---go语言基本类型
- go 学习1【基本语法】
- Go语言学习(三)-----变量、基本类型
- go学习(二)——基本数据类型和基本语法
- Java语言学习一:基本语法
- 【原创】用一个登陆的例子详细学习ObjectC基本语法
- go基本语法学习笔记之面向对象
- go基本语法学习笔记之并发编程
- 轻松学习JavaScript二:JavaScript语言的基本语法要求
- go学习笔记(14)-基本语法-结构