golang学习记录

li_amy · · 2308 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

2012/06/17 Fri.

一.Go语言的基础组成

 (1)包声明 package main //必须在非注释的第一行指出当前文件属于哪一个包。Package main表示一个可独立执行的程序,每个go应用都包含一个名为main的包

 (2)引入包 import “fmt” // 格式上注意使用了双引号,fmt包包含了实现了格式化I/O(输入/输出)的函数

 (3)函数 func main(){ //如果有init()函数则限制性init()函数,否则main函数将是程序启动时第一个被执行的函数

 (4)注释  /*。。。*/

   (5)  变量 //该程序无变量

 (6)语句&表达式 fmt.Println("Hello,World") // 格式上注意无分号,Print和Println

    }

 (7)标识符 (常量,变量,类型,函数名,结构字段) 

阅读规则:“Group1,使用大写字母开头的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的private)。


二.Go语言基础语法

1.Go标记

Go程序由标记组成. 标记可以是关键字, 标识符(常量,变量,类型,函数名,结构字段), 常量, 字符串, 符号

e.g

fmt.Println("Hello, World!")
共6个标记

fmt 标识符 .符号 Println标识符 (符号 "Hello,World!"字符串 )符号

2.行分隔符

在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号结尾,若一行多句,则需要加上分号.

3.注释

4.标识符

 命名规则:一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。(区别不大)

5.关键字或保留字

下面列举了 Go 代码中会使用到的 25 个关键字或保留字:

break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符:

append bool byte cap close complex complex64 complex128 uint16
copy false float32 float64 imag int int8 int16 uint32
int32 int64 iota len make new nil panic uint64
print println real recover string true uint uint8 uintptr

程序一般由关键字、常量、变量、运算符、类型和函数组成。

程序中可能会使用到这些分隔符:括号 (),中括号 [] 和大括号 {}。

程序中可能会使用到这些标点符号:.、,、;、: 和 …。

6.Go语言的空格

Go 语言中变量的声明必须使用空格隔开,如:

var age int;
三. Go语言数据类型
1.意义:数据类型的出现是为了把数据分成所需内存大小不同的数据.编程时需要大数据时才申请大内存,这样就可以充分利用内存了.
2.
序号 类型和描述
1 布尔型
布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。
2 数字类型
整型 int 和浮点型 float,Go 语言支持整型和浮点型数字,并且原生支持复数,其中位的运算采用补码。
3 字符串类型:
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。
4 派生类型:
包括:
  • (a) 指针类型(Pointer)
  • (b) 数组类型
  • (c) 结构化类型(struct)
  • (d) 联合体类型 (union)
  • (e) 函数类型
  • (f) 切片类型
  • (g) 接口类型(interface)
  • (h) Map 类型
  • (i) Channel 类型
2-数字类型
Go 也有基于架构的类型,例如:int、uint 和 uintptr。

四.Go语言变量
1.变量的意义:
变量来源于数学,在计算机语言中,变量被用于储存计算结果或表示值。可以通过变量 名访问。
2. 变量声明
关键字(keyword) var
(1)单变量声明
①指明变量类型,声明后若不赋值,则使用默认值
var var_name var_type  //注意顺序
var_name=value
②根据值自行判断变量类型//类似于python
var v_name=value
③省略var,注意:=左侧的变量不应该是声明过的,某则编译错误.
v_name:=value
e.g.
package main
var a = "w3cschool菜鸟教程"
var b string = "w3cschool.cc"
var c bool

func main(){
    println(a, b, c)
}
输出为:
w3cschool菜鸟教程w3cschool.cc fasle
②①③(bool默认值为false)
(2)多变量声明
①类型相同的多个变量,非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 =v1, v2, v3
②不显示声明类型
var vname1, vname2,  vname3=v1, v2, v3
③这种不带声明格式的只能在函数体中出现,//即不能出现在fun 大括号的外面
这被称为 并行 或 同时 赋值
vname1, vname2, vname3:= v1, v2, v3
**** ④ 因式分解关键字的写法,一般用于声明全局变量
var {
vname1 v_type1
vname2 v_type2
}
e.g.
package main

var x, y int
var (  // 这种因式分解关键字的写法一般用于声明全局变量
    a int
    b bool
)

var c, d int = 1, 2
var e, f = 123, "hello"

//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"

func main(){
    g, h := 123, "hello"
    println(x, y, a, b, c, d, e, f, g, h)
}
输出
0 0 0 false 1 2 123 hello 123 hello

3.变量的分类:值类型和引用类型
(1)值类型:
像是int, float, bool和string这些基本类型都属于值类型, 使用这些类型的变量直接指向存在内存中的值.
当使用=将一个变量的值赋给另一个变量时,如j=i, 实际上是在内存中将i的值进行了拷贝
可以通过&i来获取变量i的内存地址(内存地址会根据机器不同而有所不同,甚至相同的程序在不同的机器上执行也会有不同的内存地址,因为每台机器可能会有不同的存储器布局,并且为之分配也可能不同), 值类型的变量的值存储在栈(stack)中.
(int) i -> 7
(int) j-> 7
(2)引用类型
存在意义:
更复杂的数据通常会使用多个字,这些数据以便使用引用类型保存 //数据本身要占用多个字,若仍像是值类型多次复制粘贴,将会耗费很多内存
一个引用类型的变量r1存储的是r1的值所在的内存地址(数字),或内存地址中第一个字所在的位置.
这个内存地址被称为指针,这个指针实际上也被存在另外的某一个字中
当使用r2=r1时,只有引用(地址)被复制,乳沟r1的值被改变了,那这个值所有的引用都会被指向修改后的内容,r2也会受到影响.

(ref) r1 -> address1 -> value of r1 //address1和address2都指向value of r1
(ref) r2 -> address2->             
同一个引用类型的指针指向的多个字可以是在连续的内存地址中(内存布局是连续的),这也是计算效率最高的一种存储形式;也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址.

4. 关于上文中使用的:=赋值操作符

a := 50 或 b := false,a 和 b 的类型(int 和 bool)将由编译器自动推断,这是使用变量的首选形式.

但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。

使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明


5.Notice
(1)变量名的命名应符合标识符的命名规则

(2)如果你声明了一个局部变量没有在相同的代码块中使用它,同样会得到编译错误,例如下面这个例子当中的变量 a:

func main() {
   var a string = "abc"
   fmt.Println("hello, world")
}

尝试编译这段代码将得到错误 a declared and not used

此外,单纯地给 a 赋值也是不够的,这个值必须被使用,所以使用

fmt.Println("hello, world", a)

会移除错误。

但是全局变量是允许声明但不使用。

(3)交换两个变量的值,则可以简单地使用 a, b = b, a。
(4)空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。_ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值
(5)并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和错误 err 是通过调用 Func1 函数同时得到:val, err = Func1(var1)。

五.Go语言常量
1.常量的定义

常量是一个简单值的标识符,在程序运行时,不会被修改的量。

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型,不可以是衍生类。

2.常量的定义格式

常量的定义格式:

const identifier [type] = value

可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。

  • 显式类型定义: const b string = "abc"
  • 隐式类型定义: const b = "abc"

多个相同类型的声明可以简写为:

const c_name1, c_name2 = value1, value2
/*以上类比Go语言变量*/

3.Go语言常量的不同用法
e.g.
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)   
}
输出
面积为 : 50
1 false str

常量还可以用作枚举:

const (
    Unknown = 0
    Female = 1
    Male = 2
)

数字 0、1 和 2 分别代表未知性别、女性和男性。

常量可以用len(), cap(), unsafe.Sizeof()常量计算表达式的值。常量表达式中,函数必须是内置函数(嵌入到主调函数中的函数称为内置函数,又称内嵌函数。 它的作用:提高程序的执行效率。 声明内置函数:只需在函数首行的左端加一个关键字inline即可。),否则编译不过:

package main

import "unsafe"
const (
    a = "abc"
    b = len(a)
    c = unsafe.Sizeof(a)
)

func main(){
    println(a, b, c)
}

以上实例运行结果为:

abc 3 16
4.特殊常量--iota

(1)定义

iota,特殊常量,可以认为是一个可以被编译器修改的常量。

每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1
e.g.
①连续
const (
    a = iota
    b = iota
    c = iota
)

第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:

const (
    a = iota
    b
    c
)
②间隔
package main

import "fmt"

func main() {
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //独立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢复计数
            i          //8
    )
    fmt.Println(a,b,c,d,e,f,g,h,i)
}

以上实例运行结果为:

0 1 2 ha ha 100 100 7 8
③移位
package main

import "fmt"
const (
	i=1<<iota
    j=3<<iota
    k
    l
)

func main() {
	fmt.Println("i=",i)
	fmt.Println("j=",j)
	fmt.Println("k=",k)
	fmt.Println("l=",l)
}

以上实例运行结果为:

i= 1
j= 6
k= 12
l= 24

iota表示从0开始自动加1,所以i=1<<0,j=3<<1(<<表示左移的意思),即:i=1,j=6,这没问题,关键在k和l,从输出结果看,k=3<<2,l=3<<3。




有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:li_amy

查看原文:golang学习记录

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2308 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传