Go基础

2019-02-07  本文已影响0人  无尾树袋熊

Go基础

Go与c对比

  1. Go中的注释与C的注释一样,有多行和单行,细节都一样
  2. 都是由函数组成的
  3. 入口函数都是main
  4. 一个程序只能有一个main函数, 没有main函数程序不能执行.格式:
int main(){
    逻辑语句;
    } //C语言
    
fun main(){
    逻辑语句;
    } //Go fun代表是函数 ()为形参列表 {}为函数体
  1. 如何往控制台输出内容:
#include <stdio.h>
printf("要输出的内容");//告诉系统去哪找输出函数的实现

import "fmt"//告诉系统去哪找输出函数的实现
fmt.Printf("要输出的内容");//告诉系统要输出什么内容
//例如:
func main()  {
    fmt.Printf("Hello LNJ\n")
}
  1. 保存源码的文件:
C保存在.C文件中
Go保存在.go文件中
  1. 代码的管理方式

    • C语言通过文件来管理代码会将不同的功能(模块)的代码,放到不同的文件中, 然后声明.h, 然后include导入.h文件使用对应的代码
    • Go语言通过包来管理代码, 会将不同功能(模块)的代码, 放到不同的包中,然后通过import导入包来使用对应的代码
  2. 在Go语言中,一个文件夹就是一个包

  3. 注意点:

    • 包名要和.go文件所在的文件夹的名称保持一致
    • 包名不能重复
  4. Go语言每条语句后不用添加分号,但如果两条语句在同一行就必须添加

func main() {
    fmt.Printf("Hello LNJ\n")
    fmt.Printf("Hello it666\n")
}

func main() {
    fmt.Printf("Hello LNJ\n");fmt.Printf("Hello it666\n")
}

  1. Go语言中import了一个包,没有使用会报错.C语言中不会
  2. Go语言中定义了变量后没使用会报错
  3. Go语言中函数的{必须和函数名称在同一行, 否则会报错
  4. 关键字与C语言一样
  5. GO语言中程序员自己起的名称就是标识符且只能由数字/字母/_组成, 并且不能以数字开头.与C语言一样(Go语言支持UTF-8,所以可以用中文作为标识符(不推荐))
func main()  {
    var 整数 int = 666
    fmt.Printf("%d\n", 整数)
}
  1. Go语言中也可以通过sizeof来计算数据类型占用的内存大小
import (
    "fmt"
    "unsafe"
) //导入unsafe

fmt.Println("int size = ",unsafe.Sizeof(int(0)))
//利用unsafe.Sizeof调用函数
//int类型,会根据当前系统自动调整, 如果系统是64位的,int就会自动变成int64, 如果系统是32位的, int就会自耦单变成int32
  1. 字符类型:byte相当于C语言中的char, 专门用于保存一个字符.rune本质是int32,专门用于保存一个中文字符(==GO语言默认支持中文,默认按照UTF-8来处理,在UTF-8中一个中文占3个字节,在Windows中一个中文占2个字节,在Linux中一个中文占3个字节,非常不方便做兼容处理==)
fmt.Println("byte size = ", unsafe.Sizeof(byte(0))) //1
fmt.Println("rune size = ", unsafe.Sizeof(rune(0))) //4

变量

  1. 可以改变的数据称为变量
  2. 定义变量的意义:告诉操作系统,需要分配多大的空间来存储数据
  3. 格式:
var 变量名 数据类型:

var num int
  1. 先定义再初始化,定义的同时初始化
var num int
num = 666
fmt.Printf("%d\n",num)

var num int = 666
fmt.Printf("%d\n",num)
  1. 如果定义的同时初始化,那么定义变量时,数据类型可以省略.除了可以省略数据类型以外,还可以==利用:=继续省略var==(系统会自动根据赋值推倒变量的类型)
var num = 666
fmt.Printf("%d\n",num)
fmt.Printf("%T\n",num) //%T输出变量的数据类型,输出整型只能用%d

num := 666 //不可以写数据类型和var
fmt.Printf("%d\n",num)
//:=先定义一个变量,不能当作=来使用
  1. 连续定义变量:
var a, b, c int
a = 666
b = 111
c = 222

var a, b, c int= 10, 20, 30
a, b, c, = 10, 20, 30
//变量组 不能使用:=
var (
    a int
    b int
    c int
)

var(
    a = 10
    b = 20
    c = 30
)
  1. Go语言中的全局变量,只要定义了,在定义之前和定义之后都可以使用
func testi(){
    fmt.Printf(format:"%d\n",value)
}
var value int//全局变量
  1. Go语言中局部变量的作用域和C语言一样
  2. Go语言局部,全局变量的生命周期和C语言一样
  3. Go语言和C语言一样,相同的作用域内,不能出现同名的==局部变量==
  4. Go语言中相同的作用域内,不能出现同名的==全局变量==(与C语言不一样)
  5. 全局变量未初始化,C与Go都默认为0.局部变量未初始化,C默认为垃圾数据,Go默认为0
  6. 局部变量如果没有使用, 编译会报错,全局变量如果没有使用, 编译不会报错
  7. :=只能用于局部变量,不能用于全局变量
  8. :=如果用于同时定义多个变量, 会有退化赋值现象(==如果通过:=定义多个变量,但是多个变量中有的变量已经在前面定义过了,那么只会对没有定义过的变量执行:=,而定义过的变量只执行=操作==)
num := 123
num, value := 456, 789
fmt.Printf("%d, %d", num, value)
  1. 类型转换:Go语言只有显示转换,没有隐式转换
数据类型(被转换的数据)
var num int = 3.14 // 报错
var num int = int(3.14) //不能对常量进行强制转换

var num float64 = 3.14
var value int = int(num) //只能对变量进行转换
fmt.Printf("%d\n",value)

//在Go语言中数据类型必须一样,才能赋值
var num int32 = 666
var value int64 = num //报错
var value int32 = num //正确

//特殊情况
var ch byte = 'a'
var num uint8 = ch

var ch rune = '雪'
var num uint32 = ch //报错

//bool类型不能强转为整型
var flag bool = false
var num int = int(flag) //报错

//整型也可以通过T(v)转换为字符串类型(不推荐)
var num int = 97
var str string = string(num)

  1. 将基本数据类型转换为字符串类型的方式:
// strconv.FormatXxx()
//1.
var num int = 9
var str string = strconv.FormatInt(int64(num),10)
//第一个参数:需要转换的整数,必须是int64类型的
//第二个参数:转换为多少进制的字符串
fmt.Printf("%s\n",str)

//2.
var num float32 = 3.1234567890123456789
var str string = strconv.FormatFloat(float64(num), 'f', -1, 32)
// 第一个参数:需要转换的小数, 必须是float64类型的
// 第二个参数:按照什么格式转换 'f'小数格式 'e' 指数的格式
// 第三个参数: 保留多少位小数, 传入-1按照原始类型的精度保留
// 第四个参数: 原始类型的标志  float32 --> 32  float64 --> 64


//strconv.Itoa()
var num int64 = 666
var str string = strconv.Itoa(int(num))//无法转换小数
fmt.Printf("%s\n", str)
  1. 将字符串类型转换为基本数据类型
// 1.strconv.ParseXxx()
var str string = "1001"
num, err := strconv.ParseInt(str, 10, 8)
/*
返回值1:转换后的数值,int64
返回值2:转换成功后返回nil,失败则不是nil
参数1:需要转换的字符串
参数2:被转换的字符串保存为多多少进制的
参数3:要转换为多少位整数(被转换的字符串超出了指定长度会报错)
*/

var str string = "3.1234567890123"
num, err := strconv.ParseFloat(str, 64)
/*
参数1:需要转换的字符串
参数2:转换为单精度还是双精度.32或64
返回值1:转换后的小数
返回值2:转换成功后返回nil,失败则不是nil
*/

// 2.strconv.Atoi()
var str string = "9"//不能转换小数
num, err := strconv.Atoi(str)

函数基础

  1. 格式:
/*
func 函数名(形参列表)(返回值列表){
    逻辑语句
}
*/
func calculate()(int, int){
    return 10, 20
}

常量

  1. 格式:
const 常量名称 数据类型 = 值
/*
注意点:
1.数据类型可以省略,const不能省略
2.定义变量不能用 :=
3.局部变量未使用会报错.定义常量和全局变量未使用不会报错
4.可以连续定义常量
5.常量组中,没有赋值,默认值就是上一行的取值
*/
const num int = 666
const a, b, c int = 10, 20, 30
const a, b, c = 10, 20, 30
//常量组:
const (
    a = 10
    b = 20
    c = 30
)

const (
    a = 10
    b = 20
    c       //默认为20
)

const(
    a, b = 10, 20
    c, d //10 20
)
  1. 枚举
    Go语言没有明确定义枚举的固定写法,企业开发中一般会用常量组的形式表示枚举
/*
const (
    枚举元素 = 值
    枚举元素 = 值
)
*/
const(
    male = 0
    female = 1
)
/*
1.iota迭代器,默认从0开始
2.常量组中只要出现了iota,后续的常量都会依次递增1
3.如果常量组中的iota被打断了, 那么就不会继续递增
4.如果常量组中的itoa被打断了, 但是后续又被回复了,那么前面有多少行就会递增多少
*/
const(
    male = iota //1
    female      //2
    yao         //3
)
const(
    male = iota //1
    female = 666//666
    yao         //666
)
const(
    male = iota //1
    female = 666//666
    yao = iota  //3
)

输出函数

  1. fmt.Printf("格式化字符串", 数据列表)
num, value := 10, 20
fmt.Printf("num = %d, value = %d\n",num, value)
  1. fmt.Println(数据列表) 会自动换行
num, value := 10, 20
fmt.Printf("num = ",num "value = ",value)

输入函数

  1. fmt.Scanf(格式化字符串,地址列表)
    • 如果接收的不是字符串类型(%c),会忽略空格和TAB
var num int;
fmt.Scanf("%d",&num)
  1. fmt.Scan(地址列表)
    • 如果接收的不是字符串类型(%c),会忽略空格和TAB和回车
var num int;
var value int;
fmt.Scan(&value,&num)
  1. fmt.Scanln(地址列表)
    • 如果接收的不是字符串类型(%c),会忽略空格和TAB
var num int;
var value int;
fmt.Scanln(&value,&num)

命令行参数

  1. Go语言中main函数不接受任何参数,但可以通过其它方式接收
    1. 导入os包,通过os包的Args属性获取命令行参数
    2. 注意点:默认会将当前被执行程序的可执行文件的路径传递.无论外界传入的数据类型是什么,os包拿到的都是字符串类型.必须按照顺序传递,少传参会报错
    var exePath = os.Args[0]
    var name = os.Args[1]
    var age = os.Args[2]
    
    1. 导入flag包,通过flag包中的stringVar函数获取
    2. 少传参,不会报错.不用按照顺序传递参数
    var name string
    /*
    参数1:数据保存位置
    参数2:用于接收的字段名称(-name = yzf)
    参数3:没有传递参数时的默认值
    参数4:用户输入--help的时候的提示信息
    */
    flag.String(&name,"name","默认名称","接收用户名")
    var age string
    flag.String(&age,"age","-1","接收用年龄")
    
    //通过flag包接收用户输入的命令行参数,还必须将编写好的参数注册到命令行
    flag.Parse()
    

算数运算符

  1. ++ -- / % * + - 用法与c语言一样
  2. 注意点:
    1. 不同类型的常量(字面量)可以运算
    2. 不同类型的变量不可以直接进行运算
    num1 := 10
    num2 := 3.0
    res1 := num1 / num2  //报错
    res2 := float64(num1) / num2
  1. 注意点: +还可以用于拼接字符串
var str1 string = "lnj"
var str2 string = "it66"
var str3 string = str1 + str2
//只有相同类型才能运算
var res string = "lnj" + 7 //报错
  1. 注意点:
    Go语言中++ --只能写在后面,不能写在前面
num := 1
fmt.Println(num) //1
num++
fmt.Println(num) //2
num--
fmt.Println(num) //1

++num //报错

关系运算符

  1. Go语言中的关系运算符: > < >= <= == !=
  2. 注意点:C语言中非零即真,Go中没有这个概念,关系运算符返回的都是true或false
  3. 优先级:==不用记,记住()最高即可==
res := 10 > 5
fmt.Println(res) //true

逻辑运算符

  1. C与Go语言的逻辑运算符一样:&& || !
  2. 注意点:
    1. Go语言中的逻辑运算符返回值是true或false
    2. 参与运算的表达式的返回值必须都是布尔类型
  3. 规则:
&& 一假则假
|| 一真则真
! 真变假,假变真

res1 = (10 > 5)&&(1 > 1) //false
res2 = 1 && 1 //报错,两边都必须是布尔类型
res3 = !0 //报错,必须是布尔类型
res4 = (10 > 5)||(1 > 1) //true

位运算符

  1. Go与C一样:& | ^ << >> 多了一个^&
  2. 位运算专门用于计算二进制的
    1. & 一假则假
    2. | 一真则真
    3. ^ 不同为真,相同为假
    4. .<< 乘以2的左移多少次幂
    5. .>> 除以2的左移多少次幂
    6. &^ 逻辑清零(如果b的二进制当前位是1,那么就清零.如果不是1,就保留a对应二进制数据)
a := 6
b := 11
res1 = a & b // 2
res2 = a | b // 15
res3 = a ^ b //13

num := 3
num = num << 2 //12
num = num >> 2 //3

   0110 a
&^ 1011 b
-----------
   0100

a1 := 6
b1 := 11
res1 := a1 &^ b1 //4

赋值运算符

  1. Go与C一样: = += *= /= %= &= |= ^= <<= >>= 只不过多了一个&^=
num &^ = 5 // num = num &^ 5

其它运算符

  1. Go与C一样: &取地址运算符,*访问地址运算符
var num := 10
var p *int
p = &num
fmt.Println(*p)
上一篇下一篇

猜你喜欢

热点阅读