第一部分:基本数据类型和操作符

1. 文件名&关键字&标识符

(1)所有go源码以.go结尾
    (2)标识符以字母或下划线开头,大小写敏感,比如:

a. boy     b. Boy     c. a+b     d. 0boy     e. _boy     f. =_boy     g. _

其中:a  b  e符合表示符的命名规范

(3) _是特殊标识符,用来忽略结果
    (4)保留关键字

2. Go程序基本结构

package main

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

(1) 任何一个代码文件隶属于一个包

(2)import 关键字,引用其他包:
         import("fmt")
         import("os")
        通常习惯写成:
        import (
            "fmt"
            "os"
        )

(3) golang可执行程序,package main,
         并且有且只有一个main入口函数
(4)包中函数调用:
         a. 同一个包中函数,直接调用
         b. 不同包中函数,通过包名+点+函数名进行调用
(5)包访问控制规则:
        a. 大写意味着这个函数/变量是可导出的
        b. 小写意味着这个函数/变量是私有的,包外部不能访问

准备:先创建F:\Go\project\src\go_dev\day2目录,并在该目录下创建example1,example2目录,并在example2目录下创建add,main,test目录

练习1. 写一个程序,对于给定一个数字n,求出所有两两相加等于n的组合。比如: 对于n=5,所有组合如下所示:

0 + 5 = 5
        1 + 4 = 5
        2 + 3 = 5
        3 + 2 = 5
        4 + 1 = 5
        5 + 0 = 5

在F:\Go\project\src\go_dev\day2\example1目录下创建main.go文件

 package main 

 import "fmt"

 func list(n int) {
for i := ; i <= n; i++ {
fmt.Printf("%d + %d = %d\n", i, n - i, n)
}
} func main() {
list()
}

练习1

练习2:一个程序包含两个包add和main,其中add包中有两个变量:Name和age。请问main包中如何访问Name和age?

先来看下面例子1:

 package main 

 import "fmt"

 func test() {
fmt.Println(str)
} func main() {
test()
} var str string = "hello world"

运行结果:

注意: 我们定义了一个全局变量 str 为字符串类型,可以看出在程序运行时,全局变量是先被初始化, 且不像C语言,全局变量初始化与其位置无关。

例子2:

在add目录下创建add.go文件,内容如下

 package add

 var Name string = "hello world"
var age int =

在main目录下创建main.go文件,内容如下

 package main 

 import (
"fmt"
"go_dev/day2/example2/add"
) func main() {
fmt.Println("Name = ", add.Name)
fmt.Println("age = ", add.age)
}

运行该程序:

报错的原因是:在go中变量首字母大写表示该变量可以导出,由于age首字母小写无法导出所以报错,解决方法就是将 age -> Age。

改完之后运行结果如下:

练习3: 包别名的应用,开发一个程序,使用包别名来访问包中的函数?

其中add.go不变,main.go如下: 其中在引入包前面加别名(a "go_dev/day2/example2/add")

 package main 

 import (
"fmt"
a "go_dev/day2/example2/add"
) func main() {
fmt.Println("Name = ", a.Name)
fmt.Println("age = ", a.Age)
}

运行结果:

练习4: 每个源文件都可以包含一个init函数,这个init函数自动被go运行框架调用。开发一个程序演示这个功能?

首先再来看下练习2:

add.go

 package add

 var Name string
var Age int Name = "hello world"
Age =

main.go

 package main 

 import (
"fmt"
a "go_dev/day2/example2/add"
) func main() {
fmt.Println("Name = ", a.Name)
fmt.Println("age = ", a.Age)
}

运行结果:

结果分析:报错的原因是 Name = "hello world" 和 Age = 10没有放在函数体里面

修改add.go为:

 package add

 var Name string
var Age int func Change() {
Name = "hello world"
Age =
}

注意:add.go方法名Change首字母必须大写,否则无法导出被外部调用。

修改main.go为:

 package main 

 import (
"fmt"
a "go_dev/day2/example2/add"
) func main() {
a.Change()
fmt.Println("Name = ", a.Name)
fmt.Println("age = ", a.Age)
}

运行结果:

再来看练习4:

add.go将Change修改为init,init函数自动被go运行框架调用

 package add

 var Name string
var Age int func init() {
Name = "hello world"
Age =
}

add.go

main.go

 package main 

 import (
"fmt"
a "go_dev/day2/example2/add"
) func main() {
fmt.Println("Name = ", a.Name)
fmt.Println("age = ", a.Age)
}

main.go

运行结果:

练习5: 包的只初始化,不引用。请开发一个程序,演示这个做法?

add.go

 package add

 import(
_ "go_dev/day2/example2/test"
) func init () {
Name = "hello world"
Age = } var Name string = "xxxxx"
var Age int =

add.go

test.go(在test目录下创建)

 package test

 import(
"fmt"
) var Name string = "this is in test package"
var Age int = func init() {
fmt.Println("this is a test")
fmt.Println("test.package.Name=", Name)
fmt.Println("test.package.age=", Age) Age =
fmt.Println("test.package.age=", Age)
}

test.go

main.go

 package main 

 import (
"fmt"
a "go_dev/day2/example2/add"
) func main() {
fmt.Println("Name = ", a.Name)
fmt.Println("age = ", a.Age)
}

main.go

下运行结果:

结果分析:

(1)在add.go中的 _ 表示包的只初始化(只执行test.go中的init函数),不引用。

(2)变量 Name和Age在每个包里面是相互独立的,在test.go中修改Name和Age并不会影响add.go中的这两个变量

(3)在add.go中,init函数是在全局变量Name和Age的前面,但是其值依然被改变(执行顺序是先初始化全局变量->init,因此值会被改变)。

3. 函数声明和注释

(1)函数声明: func 函数名字 (参数列表) (返回值列表){}

例如:

func add() {
} func add(a int, b int) int {
} func add(a int, b int) int, int {
}

(2)注释,两种注释,单行注释: // 和多行注释  /* */

//add 计算两个整数之和,并返回结果
func add(a int, b int){
} /*add 计算两个整数之和,
并返回结果*/
func add(a int, b int){
}

4. 常量和变量

常量:

(1)常量使用const 修饰,代表永远是只读的,不能修改。
(2)const 只能修饰boolean,number(int相关类型、浮点类型、complex)和string。
(3)语法:const identifier [type] = value,其中type可以省略。

const b string = "hello world"
const b = "hello world"
const Pi = 3.1415926
const a = /
const c = getValue() //error

(4)比较优雅的写法:

const (
a =
b =
c =
)

(5)更加专业的写法:

const (
a = iota
b //
c //
)

练习6:定义两个常量Man=1和Female=2,获取当前时间的秒数,如果能被Female整除,则在终端打印female,否则打印man。

 package main

 import (
"fmt"
"time"
) const (
Man =
Female =
) func main() {
for {
cur_time := time.Now().Unix()
if (cur_time % Female == ) {
fmt.Println("Female")
} else {
fmt.Println("Man")
}
//time.Sleep(1000 * time.Millisecond)
time.Sleep(time.Second)
}
}

练习6

变量:

语法:var identifier type

例1:

var a int
var b string
var c bool
var d int =
var e string = "hello world"

例2:

var (
a int //默认为0
b string //默认为""
c bool //默认为false
d int =
e string = "hello world"
)

例3:

var (
a int //默认为0
b string //默认为""
c bool //默认为false
d =
e = "hello world"
)

练习7:写一个程序获取当前运行的操作系统名称和PATH环境环境变量的值,并打印在终端。

 package main 

 import (
"fmt"
"os"
) func main() {
var go_root = os.Getenv("GOROOT");
fmt.Printf("The go root is: %s\n", go_root)
var path = os.Getenv("PATH")
fmt.Printf("Path is: %s\n", path)
}

练习7

5. 值类型和引用类型

值类型:变量直接存储值,内存通常在栈中分配。比如:基本数据类型int、float、bool、string以及数组和struct。

引用类型:变量存储的是一个地址,这个地址存储最终的值。内存通常在堆上分配。通过GC回收。比如:引用类型:指针、slice、map、chan等都是引用类型。

例8: 写一个程序用来打印值类型和引用类型变量到终端,并观察输出结果。

 package main

 import (
"fmt"
) func modify(a int) {
a =
} func modify1(a *int) {
*a =
} func main() {
a :=
b := make(chan int, ) fmt.Println("a=", a) //a= 5
fmt.Println("b=", b) //b= 0xc0420320e0 modify(a)
fmt.Println("a=", a) //a= 5
modify1(&a)
fmt.Println("a=", a) //a= 10
}

例8

例9:写一个程序,交换两个整数的值。比如: a=3; b=4; 交换之后:a=4;b=3。

 package main

 import "fmt"

 //交换a和b的值(通过指针)
func swap(a *int, b *int) {
tmp := *a
*a = *b
*b = tmp
} //交换a和b的值
func swap1(a int, b int) (int, int) {
return b, a
} //a和b的值不会发生变化
func swap2(a int, b int) {
tmp := a
a = b
b = tmp
} func test() {
var a int8 =
// cannot use a (type int8) as type int16 in assignment
//var b int16 = a
var b int16 = int16(a) //和C语言有所不同
fmt.Printf("a=%d b=%d\n", a, b)
} func main() {
first :=
second :=
//swap(&first, &second) //first=200 second=100
//first, second = swap1(first, second) //first=200 second=100
first, second = second, first //first=200 second=100
fmt.Println("first=", first)
fmt.Println("second=", second) test()
}

练习9

6. 变量的作用域

(1)在函数内部声明的变量叫做局部变量,生命周期仅限于函数内部。

(2)在函数外部声明的变量叫做全局变量,生命周期作用于整个包,如果是大写的,则作用于整个程序。

练习10: 请指出下面程序的输出是什么?

 var a = "G"
package main() {
n()
m()
n()
} func n() {
fmt.Println(a)
} func m() {
a = ""
fmt.Println(a)
}

练习10

练习11:请指出下面程序的输出是什么?

 var a = "G"
package main() {
n()
m()
n()
} func n() {
fmt.Println(a)
} func m() {
a := ""
fmt.Println(a)
}

练习11

练习12:请指出下面程序的输出是什么?

 package main 

 var a string

 import "fmt"

 func main() {
a = "G"
fmt.Println(a)
f1()
} func f1() {
a := "O"
fmt.Println(a)
f2()
} func f2() {
fmt.Println(a)
}

练习12

7. 数据类型和操作符

数据类型:

(1)bool类型,只能存true和false
(2)相关操作符, !、&&、||

(3)数字类型,主要有int、int8、int16、int32、int64、uint8、uint16、uint32、uint64、float32、float64

(4)类型转换,type(variable),比如:var a int=8;  var b int32=int32(a)

package main

func main() {
a int
b int32
a =
b = a + a //compiler error
b = b + //ok: 5 is constant
}

(5)字符类型:var a byte 例如:var a byte = 'c'
(6)字符串类型: var str string 例如: var str string = "hello world"

字符串表示两种方式: 1)双引号   会识别转义字符

2)``(反引号) 以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果

例如:

 package main

 import "fmt"

 func main() {
var str = "hello world\n"
var str1 = `
床前明月光,
疑是地上霜。
举头望明月,
我是郭德纲。
`
var b byte = 'c' fmt.Println(str)
fmt.Println(str1)
fmt.Println(b) //
fmt.Printf("%c\n", b)
}

(7)派生类型

包括:
      (a) 指针类型(Pointer)
      (b) 数组类型
      (c) 结构化类型(struct)
      (d) Channel 类型
      (e) 函数类型
      (f) 切片类型

 package main

 import "fmt"

 //字符串反转
func reverse(str string) string {
var result string
strLen := len(str)
for i := ; i < strLen; i++ {
result = result + fmt.Sprintf("%c", str[strLen-i-])
}
return result
} //字符串反转
func reverse1(str string) string {
var result []byte
tmp := []byte(str)
length := len(str)
for i := ; i < length; i++ {
result = append(result, tmp[length-i-])
}
return string(result)
} func main() {
var str1 = "hello"
str2 := "world" //str3 := str1 + " " + str2
str3 := fmt.Sprintf("%s %s", str1, str2)
n := len(str3) fmt.Println(str3) fmt.Printf("len(str3)=%d\n", n) substr := str3[:]
fmt.Println(substr) substr = str3[:]
fmt.Println(substr) result := reverse(str3)
fmt.Println(result) result = reverse1(result)
fmt.Println(result)
}

切片

(g) 接口类型(interface)
      (h) Map 类型

格式化输出:

通用:
%v 值的默认格式表示。当输出结构体时,扩展标志(%+v)会添加字段名
%#v 值的Go语法表示
%T 值的类型的Go语法表示
%% 百分号 布尔值:
%t 单词true或false 整数:
%b 表示为二进制
%c 该值对应的unicode码值
%d 表示为十进制
%o 表示为八进制
%q 该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x 表示为十六进制,使用a-f
%X 表示为十六进制,使用A-F
%U 表示为Unicode格式:U+,等价于"U+%04X" 浮点数、复数的两个组分:
%b 无小数部分、二进制指数的科学计数法,如-123456p-;参见strconv.FormatFloat %e 科学计数法,如-1234.456e+78 %E 科学计数法,如-1234.456E+78 %f
有小数部分但无指数部分,如123. %F 等价于%f %g
根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
%G 根据实际情况采用%E或%F格式(以获得更简洁、准确的输出) 字符串和[]byte:
%s 直接输出字符串或者[]byte %q 该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示
%x 每个字节用两字符十六进制数表示(使用a-f)
%X 每个字节用两字符十六进制数表示(使用A-F) 指针:
%p 表示为十六进制,并加上前导的0x 其它flag:
+ 总是输出数值的正负号;对%q(%+q)会生成全部是ASCII字符的输出(通过转义);
- 在输出右边填充空白而不是默认的左边(即从默认的右对齐切换为左对齐);
# 切换格式:
八进制数前加0(%#o),十六进制数前加0x(%#x)或0X(%#X),指针去掉前面的0x(%#p);
对%q(%#q),如果strconv.CanBackquote返回真会输出反引号括起来的未转义字符串;
对%U(%#U),如果字符是可打印的,会在输出Unicode格式、空格、单引号括起来的go字面值;
' ' 对数值,正数前加空格而负数前加负号;
对字符串采用%x或%X时(% x或% X)会给各打印的字节之间加空格;
使用0而不是空格填充,对于数值类型会把填充的0放在正负号后面;

例如:

 package main

 import "fmt"

 func main() {
var a int =
var b bool
c := 'a' fmt.Printf("%+v\n", a) //
fmt.Printf("%#v\n", b) //false
fmt.Printf("%T\n", c) //int32
fmt.Printf("90%%\n") //90%
fmt.Printf("%t\n", b) //false
fmt.Printf("%b\n", ) //
fmt.Printf("%f\n", 199.22) //199.220000
fmt.Printf("%q\n", "this is a test") //"this is a test"
fmt.Printf("%x\n", ) //25fe665
fmt.Printf("%p\n", &a) //0xc04203c1d0 str := fmt.Sprintf("a=%d", a) //"a=100"
fmt.Printf("%q\n", str)
}

格式化输出

操作符:

(5)逻辑操作符: == 、!=、<、<=、>和 >=。

(6)数学操作符:+、-、*、/等等。

练习13:使用math/rand生成10个随机整数,10个小于100的随机整数以及10个随机浮点数?

 package main

 import (
"fmt"
"math/rand"
"time"
) func init() {
rand.Seed(time.Now().UnixNano())
} func main() {
for i := ; i < ; i++ {
a := rand.Int()
fmt.Println(a)
} for i := ; i < ; i++ {
a := rand.Intn()
fmt.Println(a)
} for i := ; i < ; i++ {
a := rand.Float32()
fmt.Println(a)
} }

练习13

练习:

14. 判断 101-200 之间有多少个素数,并输出所有素数。

 package main 

 import (
"fmt"
"math"
) func isPrime1(num int) bool {
for i := ; i < num; i++ {
if (num % i == ) {
return false
}
}
return true
} //optimization
func isPrime2(num int) bool {
for i := ; i <= int(math.Sqrt(float64(num))); i++ {
if (num % i == ) {
return false
}
}
return true
} func main(){
var m int
var n int
var primeNum int
fmt.Println("Please input start and end num >>")
fmt.Scanf("%d%d", &m, &n) for i := m; i <= n; i++ {
/*
if (isPrime(i)) {
fmt.Println(i)
primeNum += 1
}*/ if (isPrime2(i)) {
fmt.Println(i)
primeNum +=
}
} fmt.Println("primeNum = ", primeNum)
}

练习14

15. 打印出100-999中所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。例如:153 是一个“水仙花数”,因为 153=1 的三次方+5 的三次方+3 的三次方。

 package main 

 import (
"fmt"
) func isNarcNumber(num int) bool {
var i, j, k int i = num%
j = num/%
k = num/
sum := i*i*i + j*j*j + k*k*k return (sum == num)
} func main() {
var m, n int
var totalNum int
fmt.Println("Input a number(100-999) >>")
fmt.Scanf("%d%d", &m, &n)
for i := m; i <= n; i++ {
if (isNarcNumber(i)) {
fmt.Println(i)
totalNum +=
}
} fmt.Println("total narcissus number ", totalNum)
}

练习15

 package main

 import (
"fmt"
"strconv"
) func main() {
var str string
fmt.Println("Input a number(100-999) >> ")
fmt.Scanf("%s", &str) var result =
for i := ; i < len(str); i++ {
num := int(str[i] - '')
result += (num * num * num)
} number, err := strconv.Atoi(str)
if err != nil {
fmt.Printf("Can not convert %s to int\n", str)
return
} if result == number {
fmt.Printf("%d is narcissus\n", number)
} else {
fmt.Printf("%d is not narcissus\n", number)
}
}

判断一个数是否是水仙花数

16. 对于一个数n,求n的阶乘之和,即: 1! + 2! + 3!+…n !

 package main 

 import (
"fmt"
) func computFact(num int) uint64 {
var s uint64 =
var sum uint64 =
for i := ; i <= num; i++ {
s *= uint64(i)
fmt.Printf("%d!=%v\n", i, s)
sum += s
} return sum
} func main() {
var num int
fmt.Println("Input a number (greater than 1) >> ")
fmt.Scanf("%d", &num) s := computFact(num)
fmt.Println(s)
}

练习16

Go语言学习之2 包、函数、常量、数据类型、字符操作的更多相关文章

  1. Go语言学习之main包的讲解

    ### Go语言学习之main包的讲解 1.Go中main函数不支持任何返回值 2.可以通过os.Exit(0)来返回状态 func main(){ fmt.Println("hellow ...

  2. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  3. Go语言学习笔记(六) [包]

    日期:2014年7月30日   1.定义:包时函数和数据的集合.使用package关键字定义一个包,文件名不需要与包名一致,包名约定使用小写字符,Go包可以由多个文件组成,但是需要使用相同的packa ...

  4. C语言学习<输入输出函数,函数的调用>

    #include <stdio.h> /* 输入输出函数的学习 函数的调用 2017.05.25 soulsjie */ //输入连个数字求最大值 void main(){ int Max ...

  5. C语言学习笔记 (009) - 对函数的进一步讨论

    一.给main函数传参: # include <stdio.h> int main(int argc,char **argv){ printf(]); ; } 二.指向函数指针变量的定义 ...

  6. Go语言学习笔记(2)——变量、常量

    1. 变量(变量由字母.数字和下划线组成,且不能以数字开头!)      1.1 第一种 var name type // 未赋值时使用默认值 name = value 1.2 第二种: 根据所赋的值 ...

  7. R语言爬虫:Rvest包函数介绍(表格)

    Rvest 包中常用函数一览: 函数 作用 read_html() 读取 html 页面 html_nodes() 提取所有符合条件的节点 html_node() 返回一个变量长度相等的list,相当 ...

  8. Scala语言学习笔记——方法、函数及异常

    1.Scala 方法及函数区别 ① Scala 有方法与函数,二者在语义上的区别很小.Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量.换句话来说在类中定义的函数即是方法 ② Scal ...

  9. Go语言学习(十)bytes包处理字节切片

    bytes包提供了对字节切片进行读写操作的一系列函数 字节切片处理的函数比較多,分为基本处理函数,比較函数,后缀检查函数,索引函数,切割函数, 大写和小写处理函数和子切片处理函数等. 1.字节切片基本 ...

随机推荐

  1. 观实验室PPT演讲有感

    outline 一定要有 说话的语速要慢,压制住紧张的心情 提前一天发布PPT dont` argue with audience, especially professor and teachers ...

  2. Android之电话拨号和短信

    拨打电话号码,需要添加权限设置,在安装的应用程序信息中可以看到此权限信息Intent doSth=new Intent();//意图:你想做什么呢?doSth.setAction(Intent.ACT ...

  3. kali linux web程序集简述

    Burp Suite Burp Suite是一个用于执行Web应用程序安全性测试的集成平台. 它的各种工具可以无缝地协同工作,支持整个测试过程,从应用程序攻击面的初始映射和分析,到查找和利用安全漏洞. ...

  4. Linux下查看网卡驱动和版本信息

    Linux下查看网卡驱动和版本信息 查看网卡生产厂商和信号 查看基本信息:lspci 查看详细信息:lspci -vvv # 3个小写的v 查看网卡信息:lspci | grep Ethernet 查 ...

  5. 单片机中printf函数的重映射

    单片机中printf函数的重映射 一.源自于:大侠有话说 1.如果你在学习单片机之前学过C语言,那么一定知道printf这个函数.它最最好用的功能 除了打印你想要的字符到屏幕上外,还能把数字进行格式化 ...

  6. 【转】java提高篇之理解java的三大特性——多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  7. topcoder srm 410 div1

    problem1 link 不包含$gridConnections$ 的联通块一定是连在所有包含$gridConnections$的联通块中最大的那一块上. import java.util.*; i ...

  8. freeswitch控制台日志级别设置以及存储

    1.在管理控制台上设置 console loglevel (0~7)越往上级别越大 2.打开sip详细日志 sofia profile internal siptrace on 3.关闭sip详细日志 ...

  9. VS2015密钥

    Visual Studio Professional 2015简体中文版(专业版)KEY:HMGNV-WCYXV-X7G9W-YCX63-B98R2Visual Studio Enterprise 2 ...

  10. (转)Swagger2 & Postman工具使用

    (二期)7.swagger2与postman [课程七]swagge...tman.xmind0.3MB [课程七预习]sw...tman.xmind31.3KB 随着互联网技术的发展,现在的网站架构 ...