golang语言基础(一)

0.项目的组织结构:

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

 

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中没有private,public关键字,所以以此来区分

 

5.运算符

5.1算术运算符

 5.2关系/比较运算符

5.3逻辑运算符

 

5.4赋值运算符

5.5位运算符

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

5.7运算符优先级

 
  
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)函数名大写时,才能跨包使用!!!!!!!!!!!!!!!!!!!!!!!!

 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()的原理图:

fn02()的原理图:

 8.2golang函数相关特性:

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之前,完成初始化工作)

 

转载于:https://www.cnblogs.com/psy-code/p/9613558.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值