golang语言基础(一)

0.项目的组织结构:

GOPATH路径下是src文件夹---->src文件夹下是项目名称---->项目名称下是该项目的各个包名---->各包名下是.go文件(一个包下,无论有多少个.go文件,同一个包下的.go文件中的方法名不得重复)

golang语言基础(一)

1.基础相关

package main

import "fmt"

// 入口函数
func main() {
fmt.Println("hello world")
fmt.Println("good morning")
hello()
s, minus := sum(2, 3)
fmt.Println(minus)
fmt.Println(s)
var name = "tom"
fmt.Println(name)
convertCharacter()
} // Go官方推荐用单行注释来注释代码
func hello() {
fmt.Println("ddd")
} // 求和,求差与多个返回值
func sum(i int, j int) (sum int, minus int) {
sum = i + j
minus = j - i
return sum,minus
} // 转义
func convertCharacter() {
// 制表符
fmt.Println("a\tb\tc")
// 换行符
fmt.Println("a\nb")
// 一个\
fmt.Println("\\hh")
// 一个"
fmt.Println("\"")
// 一个回车
fmt.Println("a\rb")
// demo
fmt.Println("姓名\t\t年龄\t\t籍贯\t\t性别\n张三\t\t23\t\t上海\t\t女")
}

2.变量相关

package main

import (
// 若没有用到某个包,又不删除,则在其前部加上下划线即可
"fmt"
"unsafe"
"strconv"
) func main() {
fmt.Println(g1, g2, g3, g4)
fn01()
fn02()
fn03()
fn04()
fn05()
fn06()
fn07()
fn08()
fn09()
fn10()
fn11()
defaultFun()
fn12()
fn13()
fn14()
fn15()
} //////////////////////////定义全局变量///////////////////////////////
// 函数之外的变量是全局变量,一个文件中只能出现一个,不得重复定义
var g1 = 99
var g2 = "i love golang"
var (
g3 = "tim"
g4 = false
) //////////////////////////单变量声明/////////////////////////////////
func fn01() {
// 第一种声明变量方式:变量=var + 变量名 + 变量类型 + 值
var i int = 8
fmt.Print(i, ",")
// 该区域的数值可以在一定范围内不断变化
i = 10
fmt.Print(i, ",")
i = 90
fmt.Println(i)
// 不能令i = 'tim'或者i =false
} func fn02() {
// 第二种声明变量方式,若未赋值,则使用默认值
// int 默认值是0, string默认值是空串,小数默认是0
var i int
fmt.Println(i)
} func fn03() {
// 第三种声明变量方式:若未定义类型,则自动类型推导
var num = 1.034
fmt.Println(num)
} func fn04() {
// 第四种声明变量方式:// 第二种声明变量方式:若未定义类型,则自动类型推导
name := "jerry"
fmt.Println(name)
} ////////////////////////多变量声明////////////////////////// func fn05() {
// 第一种声明变量方式
var n1, n2, n3, n4 int
fmt.Println(n1, n2, n3, n4)
} func fn06() {
// 第二种声明变量方式
var n1, n2, n3 = 1, "tom", 100.99
fmt.Println(n1, n2, n3)
} func fn07() {
// 第三种声明变量方式
n1, n2, n3 := "jerry", 3, true
fmt.Println(n1, n2, n3)
} func fn08() {
// 程序中+号的使用
// 当都是数值型:int型,float32, float64型时,做加法运算
var (
j float64 = 1.5
k = 1.5
)
fmt.Println(k + j)
// 当都是字符串时,做拼接
fmt.Println("i am " + "tom")
} ////////////////////////golang中的基本数据类型/////////////////////////
// 基本数据类型,也称值类型,变量存的就是值
// 整型(默认是0),浮点型(默认是0),布尔型(默认false),字符串型(默认"")
func defaultFun() {
var a int
var b float32
var c float64
var d bool
var e string
fmt.Printf("基本数据类型默认值: a=%d,b=%f,c=%f,d=%v,e=%v\n",a,b,c,d,e)
}
/*
整型
有符号(正负号)
int8(-2的7次方----2的7次方减1)
int16(-2的15次方----2的15次方减1)
int32(-2的31次方----2的31次方减1)
int64(-2的63次方----2的63次方减1)
无符号(没有正负号
unit8(0----2的8次方)
unit16(0----2的16次方)
unit32(0----2的32次方)
unit64(0----2的64次方)
其他类型
int 与操作系统相关,若是64位,则等价于int64;若是32位,则等价于int32
rune 等价于int32,但表示的是unicode码
byte 等价于unit8,当要存储字符时,选用byte
unit 与操作系统相关,若是64位,则等价于int64;若是32位,则等价于int32
注意事项:
1.若未声明,则默认使用int型,如: var i = 10,则i为int型
2.查看变量类型及字节大小:切记是Printf
fmt.Printf("i的变量类型是%T,占用的字节数是%d", i, unsafe.Sizeof(i))
3.在保证功能的基础上,尽量选择占用内存较少的类型,如年龄尽量选取byte型 */
func fn09() {
var f09 = 10
fmt.Printf("f09的变量类型是%T,占用的字节数是%d\n", f09, unsafe.Sizeof(f09))
////////////字符常量用单引号包裹////////////////
// golang中没有字符类型,用byte表示
var n1 byte = 'a'
// 输出ascii值
fmt.Println("n1=",n1)
// 输出原值
fmt.Printf("n1=%c \n",n1)
// 若是超过了byte范围,则用int型
var n2 = '王'
fmt.Printf("n2=%c n2的ASCII值是%d\n",n2,n2)
// 给出一个数值,可以找出其对应的ASCII字符
var n3 = 29579
fmt.Printf("n3=%c\n",n3)
// ASCII可以进行运算
var n4 = 10 + 'm'
fmt.Println("n4=",n4)
// 字符在计算机的存取过程
// 存储: 字符-->对应码值-->二进制-->存储
// 读取: 二进制-->码值-->字符-->读取
// 字符和码值的对应关系是通过字符编码表实现的,UTF-8较为常用,go语言中编码统一设置成了utf-8
// UTF-8中,一个字母占1个字节,一个汉字占3个字节
} /*
浮点型
float32:单精度,4个字节,(-2的31次方----2的31次方减1)
float64:双精度,8个字节,(-2的63次方----2的63次方减1) 注意事项:
1.浮点型的存储分为三部分,符号位+指数位+尾数位,存储时,精度会有丢失
2.若未声明,默认使用float64型,如: var k = 9.99,则k为float64型
3.当对精度要求高时,尽量选取float64位
4.常量表示:
n1 := 5.12e3
n2 := 4e-1
*/
func fn10() {
n1 := 5.12e3
n2 := 4e-1
fmt.Println(n1, n2)
} /*
布尔类型(bool类型,占1个字节,主要用于逻辑运算,流程控制中会用到)
true
false 注意事项:
默认值是false */
func fn11() {
var b = true
fmt.Printf("b=%c b占用空间是%d\n",b,unsafe.Sizeof(b))
}
/*
string型
字符串是由一串固定长度的字符连接起来的字符序列,go中的字符串是由单个字节连接起来的 注意事项;
1.统一使用UTF-8编码
2.字符串是不可变的,一旦赋值,无法改变
3.字符串的2种表示方式:
双引号包裹: 可以识别转义字符
反引号包裹: 以字符串原生的形式输出,包括换行和转义字符,可防止攻击,输出源代码等
4.字符串拼接:
var k = "aaa" + "bbb"
k += "ccc"
*/ //////////////////golang中基本数据类型的转换///////////////////////////////
// 数值型之间的转换
// 与Java不同,golang中无论高转低还是低转高,都需要强转
// 被转换的数据,在转换后,其数据类型与转换前保持一致
func fn12() {
var n1 = 10
var n2 = int32(n1)
i := n2 + 33
fmt.Println(n1, n2, i)
} //////基本数据类型转为string类型///////////
func fn13() {
var n1 = 10 // int
var n2 = true //bool
var n3 = 3.45 // float64
var n4 byte = 35 // byte
var str string // string
str = fmt.Sprintf("%d",n1) // int转为string
fmt.Println(str)
str = fmt.Sprintf("%t", n2) // int转为bool
fmt.Println(str)
str = fmt.Sprintf("%f", n3) // int转为float64
fmt.Println(str)
str = fmt.Sprintf("%d", n4) // int转为bool
fmt.Println(str)
}
func fn14() {
var n1 = 2
var n2 = false
var n3 = 4.5
var str string
str = strconv.FormatInt(int64(n1) ,10)
fmt.Println(str)
hhh := strconv.Itoa(n1)
fmt.Println(hhh)
str = strconv.FormatBool(n2)
fmt.Println(str)
// f:格式 3:小数点后的位数 64:表示双精度
str = strconv.FormatFloat(n3, 'f', 3, 64)
fmt.Println(str)
} //////string类型转为基本数据类型///////////
func fn15() {
var str1 = "true"
var str2 = "123"
var str3 = "12.345"
// 转为bool时,会返回2个值,bool,error,可用下划线忽略error值:如果此处不是合法参数,如hello,则会直接转为false
b, _ := strconv.ParseBool(str1)
fmt.Println(b)
// 转为int:如果此处不是合法参数,如hello,则会直接转为0
// 第二个参数是进制,第三个参数分别为0(int型),8,16,32,64
i, err := strconv.ParseInt(str2, 10, 0)
fmt.Println(i, err)
// 转为float:如果此处不是合法参数,如hello,则会直接转为0
f, _ := strconv.ParseFloat(str3, 64)
fmt.Println(f) }

3.指针(值类型和引用类型)

package main

import "fmt"

func main()  {
pointer01()
pointer02()
}
/*
数据类型
基本数据类型,也称值类型
值类型包括:int,float,bool,string,struct,数组
变量存的就是值
内存通常在栈中分配
引用类型包括:指针,slice切片,map,管道chan,interface
变量存储的是一个地址,这个地址对应的空间才是真正的值
内存通常在堆中分配 */
func pointer01() {
var i = 1
// 这个地址和i的值在同一地方
fmt.Println("i在内存中的地址是:",&i)
} ////////指针变量存的是一个地址,该地址指向的空间地址才是真正的值所在
/////// i------------>0xc00004a080----(10)(值引用时,值和地址在同一处)
/////// ^
/////// ^
/////// ^
/////// ptr---------->0xc000072020----(0xc00004a080)(指针引用时,值和地址不在一处)
///////
func pointer02() {
var i = 1
var ptr *int = &i
// 取地址
fmt.Println("ptr的值是:", &ptr)
// 取值
fmt.Println("ptr的值是:", *ptr)
// 通过ptr修改i的值
*ptr = 2
fmt.Println(i)
}

4.标识符命名规范

golang语言基础(一)

golang语言基础(一)

因为golang中没有private,public关键字,所以以此来区分

golang语言基础(一)

golang语言基础(一)

5.运算符

golang语言基础(一)

5.1算术运算符

golang语言基础(一)

5.2关系/比较运算符

golang语言基础(一)

golang语言基础(一)

5.3逻辑运算符

golang语言基础(一)

golang语言基础(一)

golang语言基础(一)

5.4赋值运算符

golang语言基础(一)

golang语言基础(一)

golang语言基础(一)

5.5位运算符

golang语言基础(一)

5.6其他运算符(golang不支持三目运算符)

golang语言基础(一)

5.7运算符优先级

golang语言基础(一)


package main

import "fmt"

func main()  {
fn01()
fn02()
fn03()
fn04()
fn05()
//fn06()
//fn07()
fn08()
} // 算术运算符
func fn01() {
var i = 3
var j = 5
i2:= i + j
i3 := i - j
i4 := i * j
i5 := j / i
i6 := j % i
fmt.Println("和:",i2, ",差:", i3, ",积:", i4, ",商:", i5, ",取模:", i6)
fmt.Println((5 % 3),(5 % -3),(-5 % 3), (-5 % -3))
i ++ // 不可以 var k = i ++
fmt.Println(i)
j -- // 此外,也没有 ++j, --j这样的写法
fmt.Println(j)
} // 关系运算符
func fn02() {
fmt.Println(2 >= 3)
fmt.Println(2 != 3)
fmt.Println(3 == 3)
fmt.Println(3 < 3)
} // 逻辑运算符
func fn03() {
var age = 20
if age > 10 && age <= 30{
fmt.Println(true)
} else {
fmt.Println(false)
}
} // 赋值运算符
func fn04() {
// 两个值交换:方法1:
n1 := 3
n2 := 9
t := n1
n1 = n2
n2 = t
fmt.Println(n1, n2)
// 两个值交换;方法2:
n1 = n1 + n2
n2 = n1 - n2
n1 = n1 - n2
fmt.Println(n1, n2)
} // &(取地址) 以及 *(取指针的值) 运算符
func fn05() {
n1 := 100
fmt.Println("n1的地址是:", &n1)
ptr := &n1
fmt.Println("ptr指向的值是:", *ptr)
} // 从控制台获取用户输入
func fn06() {
var name string
var age byte
var gender string
var sal float64
var freshMan bool
fmt.Println("请输入姓名:")
fmt.Scanln(&name)
fmt.Println("请输入年龄:")
fmt.Scanln(&age)
fmt.Println("请输入性别:")
fmt.Scanln(&gender)
fmt.Println("请输入薪水:")
fmt.Scanln(&sal)
fmt.Println("请输入是否是新人:")
fmt.Scanln(&freshMan)
fmt.Printf("姓名是%v,年龄是%v,性别是%v,薪水是%v,是否是新人%v\n",name,age,gender,sal,freshMan)
} // 从控制台获取用户输入
func fn07() {
var name string
var age byte
var freshMan bool
fmt.Println("请输入姓名-年龄-是否是新人,中间用-连接")
fmt.Scanf("%s-%d-%t",&name,&age,&freshMan)
fmt.Printf("姓名是%v,年龄是%v,是否是新人%v\n",name,age,freshMan)
} //////////////////进制转换///////////////////
/*
原码,反码,补码
对于有符号的而言:
二进制的最高位为符号位,0表示正数,1表示负数
正数和0的原码,反码,补码都是一样的
负数的反码=它的原码符号位不变,其他位取反(0->1,1->0)
负数的补码=它的反码+1
计算机运行的时候,都是以!!!!!!!!!!补码!!!!!!!!!!的形式进行运算的
*/ /*
其他进制转十进制:
从最低位开始,将每个位上的数提取出来,乘以2/8/16的(位数-1)次方,然后求和
二进制转十进制:
1011转为十进制: 1*2^0+1*2^1+0*2^2+1*2^3=11
八进制转十进制:
234转为十进制: 4*8^0+3*8^1+2*8^2=92
十六进制转十进制:
12转为十进制: 2*16^0+1*16^1=18 十进制转其他进制:
将该数除以2/8/16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的进制
十进制转二进制: 56------->111000
十进制转8进制: 56------->70
十进制转16进制: 56------->38 二进制转为其他进制:
将二进制数从最右侧开始,每3位(8进制)或4位(16进制)一组,转为对应的进制即可
二进制转8进制: 11010101----------->11,010,101----------->0325
二进制转16进制: 11010101----------->1101,0101----------->0XD5 其他进制转为二进制:
将对应进制的每一位,转成对应的一个3位的(8进制)或者4位的(16进制)的数即可:
八进制转二进制: 023------------->010011
十六进制转二进制: 0x14----------->00010100 */ // 位运算符
func fn08() {
var a = 1 >> 2
var b = -1 >> 2
var c = 1 << 2
var d = -1 << 2 fmt.Println(a, b, c, d) fmt.Println(2&5) fmt.Println(2|5) fmt.Println(2^5)}
 

6.流程控制

package main

import (
"fmt"
"math/rand"
"time"
) func main() {
//fn01()
//fn02()
fn03()
fn04()
fn05()
fn06()
fn07()
fn08()
fn09()
fn10()
fn11()
fn12()
fn13()
fn14()
fn15()
fn16()
} // 流程控制;双分支if,else
func fn01() {
var age int
fmt.Println("请输入年龄")
fmt.Scanln(&age)
if age < 18 {
fmt.Println("年龄不足18周岁,不得上网")
}else {
fmt.Println("可以上网,请继续")
}
} // 流程控制:多分支 if...else if...else
func fn02() {
var score int
fmt.Println("请输入分数")
fmt.Scanln(&score)
if score >= 90{
fmt.Print("优秀")
} else if score >= 80 {
fmt.Println("良好")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不合格")
}
} // switch分支,golang中不需要加break
func fn03() {
n1 := 7
switch n1 {
case 1:
fmt.Println("周一")
case 2:
fmt.Println("周二")
case 3:
fmt.Println("周三")
case 4:
fmt.Println("周四")
case 5:
fmt.Println("周五")
case 6:
fmt.Println("周六")
case 7:
fmt.Println("周日")
default:
fmt.Println("输入的不合法")
}
} // switch表达式可省略
func fn04() {
n1 := 59
switch {
case n1 >= 90:
fmt.Println("优秀")
case n1 >= 70:
fmt.Println("良好")
case n1 >= 60:
fmt.Println("及格")
default:
fmt.Println("不及格,重考")
}
} // switch穿透:只穿透一层
func fn05() {
n1 := 10
switch n1 {
case 10:
fmt.Println("a")
fallthrough
case 20:
fmt.Println("b")
case 30:
fmt.Println("c")
default:
fmt.Println("d")
}
} // for循环
func fn06() {
sum := 0
for i := 0; i <= 100; i ++{
sum += i
}
fmt.Println(sum)
} // for循环第二种写法:sum即是增量,也是初始值
func fn07() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
// for循环第三种写法:等价于for;;,是无限循环,需要结合break来使用
func fn08() {
sum := 1
for{
if sum <= 10 {
sum += sum
} else {
break
}
sum ++
}
fmt.Println(sum)
} // 遍历字符串
func fn09() {
var str = "hello world"
// 遍历字符串1
for i := 0; i < len(str); i ++{
//fmt.Println(str[i])
fmt.Printf("%c",str[i])
}
fmt.Println()
// 遍历字符串2
for index, val := range str {
fmt.Printf("index=%d,val=%c\n",index,val)
}
fmt.Println()
} // 遍历中文字符解决方案:转为切片或者采用for...range的方式,因为它是按照字符的方式遍历的
func fn10() {
var str = "中国人"
str2 := []rune(str) //
for i := 0; i < len(str2); i ++{
fmt.Printf("%c",str2[i])
}
fmt.Println()
for index, val := range str{
fmt.Printf("index=%d,val=%c\n",index,val)
}
fmt.Println()
} /////////golang中没有while,do...while语句//////////////////// //////////////break的使用///////////////
// 随机生成数字,计算需要多少次,才生成80
func fn11(){
var count = 0
for{
// 返回1970.01.01至今的秒数
rand.Seed(time.Now().UnixNano())
n := rand.Intn(100) + 1
count ++
if n == 80 {
break
}
}
fmt.Println("本次随机生成80,共用了", count,"次")
}
// 在多层for循环中,可以给各层for循环添加label,通过break label的方式来决定终止哪一层循环
// 默认break只终止最内层循环
func fn12() {
label1:
for i := 0; i < 10; i ++{
for j := 0; j < i; j ++{
if j >= 3 {
break label1
}
fmt.Println(i + j)
}
}
} //////////////////continue的使用////////////////////
//////continue只跳出本次循环,并不终止循环
func fn13() {
for i:=0; i <= 4 ; i ++ {
if i == 3 {
continue
}
fmt.Println("continue:", i)
}
}
// 在多层for循环中,可以给各层for循环添加label,通过continue label的方式来决定跳出哪一层循环
func fn14() {
outer:
for i:=0; i<=4 ; i ++ {
for j:=0; j<=i ; j++ {
if j == 3{
continue outer
}
fmt.Println("continue label:", i + j)
}
}
}
///////////////golang支持goto语句,但是不推荐使用///////////////////////////
func fn15() {
fmt.Println("001")
goto label
// 将跳过002,003
fmt.Println("002")
fmt.Println("003")
label:
fmt.Println("004")
} /////////////return表示跳出方法或函数//////////////////
func fn16() {
for i := 0; i <= 10 ; i ++ {
fmt.Println(i)
if i == 3{
return
}
}
}

 7.golang中的包

1)包的本质是创建不同的文件夹,来存放程序文件.

2)go的每一个文件都属于一个包,go是以包的形式来管理文件和项目目录结构的

3)函数名小写时,只能在本包使用!!!!!!!!!!!!!!!!!!!!

4)函数名大写时,才能跨包使用!!!!!!!!!!!!!!!!!!!!!!!!

golang语言基础(一)

8.函数(也是一种数据类型)

8.1golang中的递归函数调用

package main

import "fmt"

func main()  {
fn01(5) // 结果依次是2,2,3,4
fmt.Println("================================")
fn02(5) // 结果是2
} func fn01(n int) {
if n > 2{
n --
fn01(n)
}
fmt.Println("n的值是:",n)
} func fn02(n int) {
if n > 2 {
n --
fn02(n)
}else {
fmt.Println("此时n的值是:",n)
}
}

fn01()的原理图:

golang语言基础(一)

fn02()的原理图:

golang语言基础(一)

golang语言基础(一)

8.2golang函数相关特性:

golang语言基础(一)

golang语言基础(一)

golang语言基础(一)

package main

import "fmt"

func main()  {
fmt.Println("1================================")
fn01(5) // 结果依次是2,2,3,4
fmt.Println("2================================")
fn02(5) // 结果是2
fmt.Println("3================================")
i := fn03(7)
fmt.Println(i)
fmt.Println("4================================")
fmt.Println(fn04(2))
fmt.Println("5================================")
n := 10
fn05(&n)
fmt.Println("n的值是:",n)
fmt.Println("6================================")
tmp := fn06
fmt.Println(tmp(1,2))
fmt.Println("7================================")
tmp01 := fn07(tmp, 5, 2)
fmt.Println(tmp01)
fmt.Println("9================================")
fmt.Println(fn09(1,2,3,4,5))
}
// demo01
func fn01(n int) {
if n > 2{
n --
fn01(n)
}
fmt.Println("n的值是:",n)
}
// demo02
func fn02(n int) {
if n > 2 {
n --
fn02(n)
}else {
fmt.Println("此时n的值是:",n)
}
}
// 斐波那契数列
func fn03(n int) (int) {
if n == 1 || n == 2 {
return 1
}
return fn03(n - 1) + fn03(n - 2)
} // demo04
func fn04(n int)(int) {
if n == 1 {
return 3
}
return 2 * fn04(n - 1) + 1
} // demo05=================指针类型,引用传递==================
func fn05(n *int) {
*n = *n + 10
fmt.Println(*n)
} // demo06========函数也是一种数据类型=====================
func fn06(n1 int, n2 int) (int) {
return n1 + n2
} func fn07(fn func(int, int) int, n1 int, n2 int) int {
return fn(n1, n2)
} // 自定义数据类型
func fn08() {
type myInt int
var n1 myInt
n1 = 80
fmt.Println(n1)
} // golang中的可变参
func fn09(n1 int, args... int) (sum int) {
sum = n1
for i := 0; i < len(args); i ++{
sum += args[i]
}
return
}

8.3init函数(在main函数之前调用,通常可以在main之前,完成初始化工作)

golang语言基础(一)

上一篇:Android 各种路径详细说明


下一篇:java:如何让程序按要求自行重启?