Go.基础篇-1
package main import "fmt"
import "math"
import "errors" func main(){
fmt.Println("Hello,World!")
fmt.Println("Hello,Red!") test_var()
test_string()
test_const()
test_Iota()
test_bit()
test_for()
test_swap()
test_swapRef()
test_sqrt()
test_sequeue()
test_select()
test_type()
test_struct()
test_map()
test_interface()
test_error()
} /*
1.第一行代码 package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,
如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包
2.fmt 包实现了格式化 IO(输入/输出)的函数
3.当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头 相当于 public ;
4.标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )
*/ /*----------------------------------------------------
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 # Go 派生类
指针类型 Pointer
数组类型
结构化类型 struct
联合体类型 union
函数类型
切片类型
接口类型 interface
Map 类型
Channel 类型 # Go 数字类型
uint8 无符号 8 位整型 (0 到 255)
uint16 无符号 16 位整型 (0 到 65536)
uint32 无符合 32 位整型 (0 到 4294967295)
uint64 无符合 64 位整型 (0 到 18446744073709551615)
int8 有符号 8 位整型 (-128 到 127)
int16 有符号 16 位整型 (-32768 到 32767)
int32 有符号 32 位整型 (-2147483648 到 2147483647)
int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807) # Go 浮点型
float32 IEEE-754 32位浮点型数
float64 IEEE-754 64位浮点型数
complex64 32 位实数和虚数
complex128 64 位实数和虚数 # Go 其他数字类型
byte 类似 uint8
rune 类似 int32
uint 32 或 64
int 与 uint 一样大小
uintptr 无符号整型,用于存放一个指针 *-------------------------------------------------------
*/ func test_var(){ // 1.指定变量类型,声明后若不赋值,使用默认值。
var a int // a = 0
// 2.缺省推导
var b =
// 3.省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误,不能用在全局声明中
c := a + b fmt.Println(a,b,c) // 声明 同一类型多个变量
var d, e, f int fmt.Println(d,e,f) // 多变量同一行赋值
var g, h int
var i string
g, h, i = , , "abc" fmt.Println(g,h,i) // :=
j, k, l := , , "def"
fmt.Println(j,k,l) // 右边的这些值以相同的顺序赋值给左边的变量,
// 所以 a 的值是 5, b 的值是 7,c 的值是 "abc"。
// 这被称为 并行 或 同时 赋值。 // 交互值
j, k = k, j
fmt.Println(j,k) // 空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃
// _ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。
// 并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和错误 err 是通过调用 Func1 函数同时得到:val, err = Func1(var1)。
} func test_string(){ // 值类型:int,float,bool,string 这些基本类型都属于值类型,使用这些类型变量直接指向内存中的值
// 当使用 = 将一个变量赋值给另一个变量时,如:j = i ,实际是在内存中将 i 的值进行了拷贝
// (int) i -> 7
// (int) j -> 7 i :=
var j = i fmt.Println(i,j) // 通过 & 取内存地址
fmt.Println(&i)
} func test_const(){
// const identifier [type] = value // 显示定义
const a string = "abc"
// 隐式定义
const b = "def"
// 多个相同类型声明
const c, d = "cccc", "dddd" fmt.Println(a,b,c,d) const LENGTH int =
const WIDTH int = var area int
area = LENGTH * WIDTH fmt.Printf("Area : %d", area)
fmt.Println() // Iota
} func test_Iota(){
// iota ,特殊常量,可以认为是一个可以被编译器修改的常量。
/*
在每一个const 关键字出现时,被重置为 0 , 在下一个const 出现之前,每出现一次iota
其所代表的数字会自动加 1 */ const (
aa = iota
bb = iota
cc = iota
) fmt.Println(aa,bb,cc) const(
a = iota //
b //
c // 2
d = "ha" // "ha" 独立值 iota += 1
e // "ha" iota += 1
f = // 100 iota += 1
g // 100 iota += 1
h = iota // 7,恢复计数
i //
) fmt.Println(a,b,c,e,f,g,h,i)
} func test_bit(){
// 位运算符对整数在内存中的二进制位进行操作
/* 位运算符 & | ^
p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1 A = 0011 1100
B = 0000 1101 ------------------ A & B = 0000 1100 A | B = 0011 1101 A ^ B = 0011 0001 // 相同为0 不相同为1 按位异或运算符"^" ~A = 1100 0011 // 每bit 倒序 ---------------------
A << 2 左移 n 位就是乘以 2 的 n 次方
A = 0011 1100
A<<2 = 1111 0000 高位丢弃,低位补0 A >> 2 右移 n 位就是除以 2 的 n 次方
A = 0011 1100
A >>2 0000 1111
*/ var a uint = // 60 = 0011 1100
var b uint = // 13 = 0000 1101
var c uint = c = a & b // 12 = 0000 1100
fmt.Printf("1. a & b = %d \n", c) c = a | b // 61 = 0000 1100
fmt.Printf("2. a | b = %d \n", c) c = a ^ b // 49 = 0011 0001
fmt.Printf("3. a ^ b = %d \n", c) c = a << //
fmt.Printf("4. a << 2 = %d \n", c) c = a >> //
fmt.Printf("5. a >> 2 = %d \n", c) // & * ---------------------------
// & 返回变量存储地址
// * 指针变量 var d int32 =
var ptr *int32 ptr = &d
fmt.Printf("d 的类型:%T \n",d)
fmt.Printf("*ptr 取值为 :%d\n",*ptr)
} func test_for(){ // for init; condition; post { }
// for condition { }
// 和 C 的 for(;;) 一样: for { }
/* for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
for key, value := range oldMap {
newMap[key] = value
}
*/ var b int =
var a int
numbers := []int {, , , } for a:=; a < ; a++ {
fmt.Printf("a = %d \n", a)
} for a < b {
a++
fmt.Printf("a = %d \n", a)
} for i,x := range numbers {
fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
} } func test_swap(){
var a int =
var b int = fmt.Printf("交换前 a = %d\n", a)
fmt.Printf("交互前 b = %d\n", b) swap(a,b) fmt.Printf("交换后 a = %d\n", a)
fmt.Printf("交互后 b = %d\n", b)
} // 值传递
func swap(x,y int) int {
var temp int temp = x
x = y
y = temp return temp
} func test_swapRef(){
var a int =
var b int = fmt.Printf("交换前 a = %d\n", a)
fmt.Printf("交换前 b = %d\n", b) swapRef(&a,&b) fmt.Printf("交换后 a = %d\n", a)
fmt.Printf("交换后 b = %d\n", b)
} func swapRef(x *int, y *int) {
var temp int temp = *x
*x = *y
*y = temp
} func test_sqrt(){
// Go 语言可以很灵活的创建函数,并作为值使用 getSquare := func(x float64) float64 {
return math.Sqrt(x)
} fmt.Println(getSquare())
println()
} // 匿名函数和闭包
// Go 语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。
// 匿名函数的优越性在于可以直接使用函数内的变量,不必申明。
func test_sequeue(){ // nextNumber 为一个函数,函数 i 为 0
nextNumber := getSequeue() fmt.Println(nextNumber())
fmt.Println(nextNumber())
fmt.Println(nextNumber())
println() next2 := getSequeue() fmt.Println(next2())
fmt.Println(next2())
fmt.Println(next2())
fmt.Println(next2())
fmt.Println(next2())
println() fmt.Println(nextNumber())
} func println(){
fmt.Println("------------------------");
} func getSequeue() func() int {
i := return func() int {
i +=
return i
}
} /*
* select 是 Go 中一个控制结构,类似于用于通信的 switch 语句。
* 每个case 必须是一个通信操作,要么发送,要么接收。 select {
case communication clause :
statement(s);
case communication clause :
statement(s);
你可以定义任意数量的 case
default :
statement(s);
} 每个case都必须是一个通信
所有channel表达式都会被求值
所有被发送的表达式都会被求值
如果任意某个通信可以进行,它就执行;其他被忽略。
如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。
否则:
如果有default子句,则执行该语句。
如果没有default字句,select将阻塞,直到某个通信可以运行;
Go不会重新对channel或值进行求值。 */
func test_select(){ var c1,c2,c3 chan int
var b1,b2,b3 int select { case c1 <- b1: // to do ?? <-
fmt.Println("c1")
case c2 <- b2:
fmt.Println("c2")
case c3 <- b3:
fmt.Println("c3") default:
fmt.Println("no communication")
} println()
} func test_type(){
// 类型转换 type_name(expression)
var sum int =
var count int =
var mean float32 mean = float32(sum)/float32(count) fmt.Printf("mean = %f\n", mean)
println()
} func test_ptr(){
/*
Go 语言
*/
} func test_struct(){
/*
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合 type struct_variable_type struct {
member definition;
member definition;
...
member definition;
} variable_name := structure_variable_type {value1, value2...valuen} */ var book1 Books
var book2 Books book1.title = "Go 语言"
book1.author = "www.w3cschool.com"
book1.subject = "Go 语言教程"
book1.id = book2.title = "Python 教程"
book2.author = "www.w3cschool.cn"
book2.subject = "Python 语言教程"
book2.id = fmt.Println("book1:", book1)
fmt.Printf("book 1 title : %s\n", book1.title)
fmt.Printf("book 1 author : %s\n", book1.author)
fmt.Printf("book 1 subjiect : %s\n", book1.subject) println()
fmt.Printf("book 2 title : %s\n", book2.title)
fmt.Printf("book 2 author : %s\n", book2.author)
fmt.Printf("book 2 subjiect : %s\n", book2.subject) println() printBook(book1)
printBook(book1) printBookRef(&book2)
printBookRef(&book2)
} func printBook(book Books){
book.title = "ddddd"
fmt.Printf("book title : %s\n", book.title)
fmt.Printf("book author : %s\n", book.author)
fmt.Printf("book subjiect : %s\n", book.subject)
book.title = "eeeee"
println()
} func printBookRef(book *Books){
book.title = "ddddd"
fmt.Printf("book title : %s\n", book.title)
fmt.Printf("book author : %s\n", book.author)
fmt.Printf("book subjiect : %s\n", book.subject)
book.title = "eeeee"
println() test_range()
} type Books struct {
title string
author string
subject string
id int
} // Range 关键字用于for 循环中迭代数组 array,切片 slice ,链表 channel 或集合 map 的元素
// 在数组和切片中它返回元素的索引值,在集合中返回 key-value 对的 key 值
func test_range(){ nums := []int { , , }
sum := for _,x := range nums {
sum += x
} fmt.Println("sum:", sum) // 在数组中使用range 将传入 index 和 值两个变量。 for i,num := range nums {
fmt.Printf("i:%d,num:%d\n", i, num)
} // range 也可以用在map 的键值对上
kvs := map[string]string { "a" : "apple", "b" : "banana"} for k,v := range kvs {
fmt.Printf("%s -> %s \n",k,v)
} // range 用来枚举 unicode 字符串,第一个是字符的索引,第二个字符(unicode 的值) 本身
for i,c := range "golang" {
fmt.Println(i,c)
} println()
test_slice()
} // slice Go 语言切片是对数组的抽象
// Go 语言数组长度不可变,在特定场景中这样的集合就不太适用,Go中提供一种灵活,功能强悍的内置类型切片
// (动态数组),与数组相比长度是不固定的,可以追加元素,在追加是可能使切片的容量增大
// 定义切片
/*
var identifier []type
切片不需要说明长度
或者使用 make() 函数来创建切片:
var slice1 []type = make([]type,len)
简写:
slice1 := make([]type,len)
指定容量:
make([]T,length,capacity)
切片初始化:
s := [] int {1, 2, 3}
直接初始化切片, [] 表示切片类型 , {1,2,3} 初始化值依次是1,2,3,其 cap = len =3 s := arr[:] // 初始化切片 s 是数组 arr 的引用 s := arr[startIndex:endIndex] // 将arr中下标 startIndex 到 endIndex -1 下的元素创建为一个新的切片 s := arr[:endIndex] 从下标 0 - endIndex-1 s := arr[startIndex:] 从 startIndex 到结尾 */ func test_slice(){
var num = make([]int, , )
printSlice(num) x := []int {,,,,,,,,}
printSlice(x) // 打印切片索引从 1 (包含),到 4 (不包含)
fmt.Println("x[1:4] == ", x[:]) // 切片默认下限 为 0
fmt.Println("x[:3] == ", x[:]) // 切片默认上限为 len(x)
fmt.Println("x[4:] == ", x[:]) y := make([]int,,)
printSlice(y) x1 := x[:]
printSlice(x1) x2 := x[:]
printSlice(x2) println()
test_copyappend()
} func test_copyappend(){
// 如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容拷贝过来
// append(),copy() 函数 var x []int
printSlice(x) // 允许追加空切片
x = append(x, )
printSlice(x) // 追加一个元素
x = append(x, )
printSlice(x) // 同事添加多个元素
x = append(x, , , )
printSlice(x) // 创建切片 是 x 容量的 2 倍
x1 := make([]int, len(x), (cap(x))*)
printSlice(x1) // copy x 到 x1
copy(x1,x)
printSlice(x1)
println()
} func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x), cap(x), x)
} /*
Go 语言 Map (集合)
Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据, key 类似于索引,
指向数据的值。
Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,因为
Map 是使用 hash 表来实现的。 定义 Map
默认是 nil
var map_variable map[key_data_type]value_data_type make 函数
map_variable = make(map[key_data_type]value_data_type) 未初始化的 map 是一个 nil map, 不能用来存放数据 */ func test_map(){
// nil
var m map[string]string
fmt.Println(m) // 初始化
m = make(map[string]string) // map 插入 key-value 对
m["France"] = "Paris"
m["Italy"] = "Rome"
m["Japan"] = "Tokyo"
m["India"] = "New Delhi" // 使用 key 遍历 map
for key := range m {
fmt.Println("Capital of",key,"is",m[key])
} // 查看元素是否存在
capital, ok := m["United States"] if(ok) {
fmt.Println("Capital of United States is", capital)
}else {
fmt.Println("Capital of United States is not present")
} // 删除元素
delete(m,"France")
fmt.Println("France is deleted") for key := range m {
fmt.Println("Capital of",key,"is",m[key])
} println() test_fac()
} // Go 语言递归
// 递归就是运行过程中调用自己
// Go 语言支持递归, 但我们在使用递归时,需要设置退出条件,否则将陷入无限循环中
func test_fac() { var i int =
fmt.Printf("%d 的阶乘 = %d\n", i ,factorial(i)) // 斐波那契数列
for j:=; j < ; j++ {
fmt.Printf("%d\t",fibonaci(j))
} fmt.Println() println() } func fibonaci(n int) int {
if n < {
return n
} return fibonaci(n-) + fibonaci(n-)
} func factorial(x int) (result int) {
if x == {
result =
} else {
result = x * factorial(x - )
} return;
} /*
Go 语言提供另外一种数据类型即接口,它把所有具有共性的方法定义在一起,
任何其他类型只要实现了这些方法就是实现了这个接口 定义:
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
} 定义结构体:
type struct_name struct {
// variables
} 实现接口方法
func (struct_name_variable struct_name) method_name1() [return_type] {
// 实现方法
} */ type Phone interface {
call()
} type NokiaPhone struct { } func (nokia NokiaPhone) call() {
fmt.Println("I am Nokia, I can call you.")
} type IPhone struct { } func (iphone IPhone) call() {
fmt.Println("I am IPhone, I can call you.")
} func test_interface() {
var phone Phone phone = new(NokiaPhone)
phone.call() phone = new(IPhone)
phone.call() println()
} /*
Go 语言通过内置的错误接口提供了非常简单的错误处理机制
error 类型是一个接口类型,定义: type error interface {
Error() string
} 我们可以在编码中通过实现 error 接口类型来生成错误信息
函数通常在最后的返回值中返回错误信息. 使用 errors.New 可返回一个错误信息 */ func test_error() { //_,err := Sqrt(4)
_,err := Sqrt(-) if err != nil {
fmt.Println(err)
}
} func Sqrt(f float64) (float64,error) { if f < {
return , errors.New("math:square root of negative number")
} return math.Sqrt(f),nil
}
------------------------------------------------------------------------------------
1.参考
https://www.w3cschool.cn/go/
Go.基础篇-1的更多相关文章
- C#多线程之基础篇3
在上一篇C#多线程之基础篇2中,我们主要讲述了确定线程的状态.线程优先级.前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程.使用Monitor锁定线 ...
- 一步步学习javascript基础篇(0):开篇索引
索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...
- 2000条你应知的WPF小姿势 基础篇<15-21>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师,对C#和WPF有着极深的热情.最为出色的是他维护了两个博客:2,000Things You Should Know ...
- ABP框架实践基础篇之开发UI层
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 说明 其实最开始写的,就是这个ABP框架实践基础篇.在写这篇博客之前,又回头复习了一下ABP框架的理论,如果你还没学习,请查看AB ...
- C#多线程之基础篇2
在上一篇C#多线程之基础篇1中,我们主要讲述了如何创建线程.中止线程.线程等待以及终止线程的相关知识,在本篇中我们继续讲述有关线程的一些知识. 五.确定线程的状态 在这一节中,我们将讲述如何查看一个线 ...
- C#多线程之基础篇1
在多线程这一系列文章中,我们将讲述C#语言中多线程的相关知识,在多线程(基础篇)中我们将学习以下知识点: 创建线程 中止线程 线程等待 终止线程 确定线程的状态 线程优先级 前台线程和后台线程 向线程 ...
- iOS系列 基础篇 03 探究应用生命周期
iOS系列 基础篇 03 探究应用生命周期 目录: 1. 非运行状态 - 应用启动场景 2. 点击Home键 - 应用退出场景 3. 挂起重新运行场景 4. 内存清除 - 应用终止场景 5. 结尾 本 ...
- iOS系列 基础篇 04 探究视图生命周期
iOS系列 基础篇 04 探究视图生命周期 视图是应用的一个重要的组成部份,功能的实现与其息息相关,而视图控制器控制着视图,其重要性在整个应用中不言而喻. 以视图的四种状态为基础,我们来系统了解一下视 ...
- iOS系列 基础篇 05 视图鼻祖 - UIView
iOS系列 基础篇 05 视图鼻祖 - UIView 目录: UIView“家族” 应用界面的构建层次 视图分类 最后 在Cocoa和Cocoa Touch框架中,“根”类时NSObject类.同样, ...
- iOS系列 基础篇 06 标签和按钮 (Label & Button)
iOS系列 基础篇 06 标签和按钮 (Label & Button) 目录: 标签控件 按钮控件 小结 标签和按钮是两个常用的控件,下面咱们逐一学习. 1. 标签控件 使用Single Vi ...
随机推荐
- 201621123023《Java程序设计》第3周学习总结
一. 本周学习总结 写出你认为本周学习中比较重要的知识点关键词,如类.对象.封装等 关键字:面向对象,类,对象,构造函数,封装,继承 用思维导图或者Onenote或其他工具将这些关键词组织起来 二.书 ...
- WEB新手之do u know caidao?
继续写题. 进入该网站,可以看到显然题目给出了一个假的flag.再看第二句话,说题目里存在shell.于是用御剑扫描一下后台. 如上图所示,扫出了一个叫shell的包.于是常识性地在URL加上shel ...
- 9、select 语句
基础语句 select * from tb1; select * from tb1 limit 3; select name,age from tb1; select name,age from tb ...
- 洛谷P4337 [ZJOI2018]线图(状压+搜索+乱搞)
题面 传送门 题解 妈呀调了我整整一天-- 题解太长了不写了可以去看\(shadowice\)巨巨的 //minamoto #include<bits/stdc++.h> #define ...
- 快速启动工具Rulers 4.1
Rulers 4.1 Release 360云盘 https://yunpan.cn/cSbq5nx9GVwrJ 访问密码 0532 百度云 http://pan.baidu.com/s/1czCNR ...
- [ActionSprit 3.0] FMS远程共享
package { import flash.display.Sprite; import flash.events.NetStatusEvent; import flash.events.SyncE ...
- Mysql创建、删除用户[转]
MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束): 1.新建用户 登录MYSQL: @>mysql -u root -p @>密码 ...
- ArchLinux下Ecplise软件报错
如果你的Java出现了一下问题:An error has occurred. See error log for more details.java.lang.NullPointerException ...
- svn命令行的使用
只是说一下,svn平时工作时常用的命令 1.svn delete 目录 删除svn版本里的相关目录 2.svn add 目录 将本地的目录添加到svn版本信息里 3.svn commit 目录 提交s ...
- js判断浏览器类型以及语言
1.检查是否是移动端(Mobile).ipad.iphone.微信.QQ等 <script type="text/javascript"> //判断访问终端 var b ...