golang

05-Go语言常量和变量-指趣学院

2018-09-16  本文已影响400人  极客江南

Go语言数据类型


类型 32位编译器 64位编译器
char 1 1
int 4 4
float 4 4
double 8 8
short 2 2
long 4 8
long long 8 8
void* 4 8
类型 32位编译器 64位编译器 本质
int8/uint8 1 1 signed char/unsigned char
int16/uint16 2 2 signed short/unsigned short
int32/uint32 4 4 signed int/unsigned int
int64/uint64 8 8 signed long long int/unsigned long long int
byte 1 1 uint8/unsigned char
rune 4 4 int32/signed int
int 4 8 根据机器位数决定长度
uintptr 4 8 根据机器位数决定长度 uint32/uint64
float32 4 4 float
float64 8 8 double
true 1 1 char类型的整型
false 1 1 char类型的整型
package main

import (
    "fmt"
    "unsafe"
)

func main() {
    fmt.Println("int size = ", unsafe.Sizeof(int(0)))
    fmt.Println("int8 size = ", unsafe.Sizeof(int8(0)))
    fmt.Println("int16 size = ", unsafe.Sizeof(int16(0)))
    fmt.Println("int32 size = ", unsafe.Sizeof(int32(0)))
    fmt.Println("int64 size = ", unsafe.Sizeof(int64(0)))
    fmt.Println("uint size = ", unsafe.Sizeof(uint(0)))
    fmt.Println("uint8 size = ", unsafe.Sizeof(uint8(0)))
    fmt.Println("uint16 size = ", unsafe.Sizeof(uint16(0)))
    fmt.Println("uint32 size = ", unsafe.Sizeof(uint32(0)))
    fmt.Println("uint64 size = ", unsafe.Sizeof(uint64(0)))
    fmt.Println("uintptr size = ", unsafe.Sizeof(uintptr(0)))
    fmt.Println("byte size = ", unsafe.Sizeof(byte(0)))
    fmt.Println("rune size = ", unsafe.Sizeof(rune(0)))
    fmt.Println("float32 size = ", unsafe.Sizeof(float32(0)))
    fmt.Println("float64 size = ", unsafe.Sizeof(float64(0)))
    fmt.Println("true size = ", unsafe.Sizeof(true))
    fmt.Println("false size = ", unsafe.Sizeof(false))

}

// 第8行到35行
typedef signed char     int8;
typedef unsigned char       uint8;
typedef signed short        int16;
typedef unsigned short      uint16;
typedef signed int      int32;
typedef unsigned int        uint32;
typedef signed long long int    int64;
typedef unsigned long long int  uint64;
typedef float           float32;
typedef double          float64;

#ifdef _64BIT
typedef uint64      uintptr;
typedef int64       intptr;
typedef int64       intgo; // Go's int
typedef uint64      uintgo; // Go's uint
#else
typedef uint32      uintptr;
typedef int32       intptr;
typedef int32       intgo; // Go's int
typedef uint32      uintgo; // Go's uint
#endif

#ifdef _64BITREG
typedef uint64      uintreg;
#else
typedef uint32      uintreg;
#endif

// 第153行到157行
enum
{
    true    = 1,
    false   = 0,
};

install B 时刻:
Go本质就是用C语言编写的一门高级编程语言
所以江哥前面教你C语言就是为了今天能让你看懂Go的实现代码,做到知其然知其所以然
注意点: 企业开发中一般使用int, 因为int会根据你当前的操作系统自动转换为int32和int64


Go语言变量

数据类型 变量名称;
数据类型 变量名称1, 变量名称2;
#include <stdio.h>

int main(int argc, const char * argv[])
{
    int num1; // 先定义
    num1 = 10; // 后初始化
    printf("num1 = %d\n", num1);

    int num2 = 20; // 定义的同时初始化
    printf("num2 = %d\n", num2);

    // 注意: 同时定义多个变量,不支持定义时初始化, 只能先定义后初始化
    int num3, num4; //同时定义多个变量
    num3 = 30;
    num4 = 40;
    printf("num3 = %d\n", num3);
    printf("num4 = %d\n", num4);

    return 0;
}
// 标准格式
var 变量名称 数据类型 = 值;
// 自动推到类型格式
var 变量名称 = 值;
// 简短格式(golang官方推荐格式)
变量名称 := 值;
package main
import "fmt"
func main() {
    var num1 int // 先定义
    num1 = 10 // 后赋值
    fmt.Println("num1 = ", num1)

    var num2 int = 20 // 定义的同时赋值
    fmt.Println("num2 = ", num2)

    var num3  = 30 // 定义的同时赋值, 并省略数据类型
    fmt.Println("num3 = ", num3)
    
    num4  := 40 // 定义的同时赋值, 并省略关键字和数据类型
    /*
    num4  := 40 等价于
    var num4 int
    num4 = 40
    */
    fmt.Println("num4 = ", num4)
}

Go语言变量定义注意点

package main
import "fmt"
func main() {
    num := 10
    num := 20 // 编译报错, 重复定义
    fmt.Println("num = ", num)
}
package main
import "fmt"
var num = 10 // 定义一个全局变量
func main() {
    num := 20 // 定义一个局部变量
    fmt.Println("num = ", num)
        test()
}
func test() {
    fmt.Println("num = ", num) // 还是输出10
}

package main
import "fmt"
num := 10 // 编译报错
func main() {
    fmt.Println("num = ", num)
}
package main
import "fmt"
func main() {
    //var num int := 10 // 编译报错
    //var num := 10 // 编译报错
    num int := 10 // 编译报错
    fmt.Println("num = ", num)
    fmt.Println("num = ", num)
}
package main
import "fmt"
func main() {
    var(
        num := 10 // 编译报错
    )
    fmt.Println("num = ", num)
}
package main
import "fmt"
func main() {
    //num1, num2 := 666, 888 // 正确
    num1, num2 := 666 // 报错
    fmt.Printf("%d, %d\n", num1, num2)
}
package main
import "fmt"
func main() {
    // 定义一个变量num1
    num1 := 10
    // 同时定义两个变量num1和num2, 由于num2从来没有定义过,
    // 所以对于num1来说:=退化为赋值运算符, 而对于num2来说:=仍然是定义+赋值
    num1, num2 := 20, 30
    fmt.Println("num1 = ", num1)
    fmt.Println("num2 = ", num2)
}
package main
import "fmt"
func main() {
    num1 := 10
    num2 := 20
    // 报错, 因为num1,和num2都已经被定义过
    // 至少要有任意一个变量没有被定义过,才会退化赋值
    num1, num2 := 30, 40
    fmt.Println("num1 = ", num1)
    fmt.Println("num2 = ", num2)
}

局部变量和全局变量

package main
import "fmt"
//var num1 int
//var num1 int // 报错, 重复定义
var num3 int
func main() {
    //var num2
    //var num2 // 报错, 重复定义
    
    var num3 int // 不报错, 因为作用域不同
    fmt.Println("num3 = ", num3)
}

package main
import "fmt"
func main() {
    var intV int // 整型变量
    var floatV float32 // 实型变量
    var boolV bool // 布尔型变量
    var stringV string // 字符串变量
    var pointerV *int // 指针变量
    var funcV func(int, int)int // function变量
    var interfaceV interface{} // 接口变量
    var sliceV []int // 切片变量
    var channelV chan int // channel变量
    var mapV map[string]string // map变量
    var errorV error // error变量

    fmt.Println("int = ", intV) // 0
    fmt.Println("float = ", floatV) // 0
    fmt.Println("bool = ", boolV) // false
    fmt.Println("string = ", stringV) // ""
    fmt.Println("pointer = ", pointerV) // nil
    fmt.Println("func = ", funcV) // nil
    fmt.Println("interface = ", interfaceV) // nil
    fmt.Println("slice = ", sliceV) // []
    fmt.Println("slice = ", sliceV == nil) // true
    fmt.Println("channel = ", channelV) // nil
    fmt.Println("map = ", mapV) // map[]
    fmt.Println("map = ", mapV == nil) // true
    fmt.Println("error = ", errorV) // nil

    var arraryV [3]int // 数组变量
    type Person struct{
        name string
        age int
    }
    var structV Person // 结构体变量
    fmt.Println("arrary = ", arraryV) // [0, 0, 0]
    fmt.Println("struct = ", structV) // {"" 0}
}

数据类型转换

#include <stdio.h>
int main(){
  // 隐式转换:自动将实型10.6转换为整型后保存
   int a = 10.6;
 // 自动类型提升: 运算时会自动将小类型转换为大类型后运算
  double b = 1.0 / 2; // 等价于1.0 / 2.0
}
#include <stdio.h>
int main(){
  // 显示转换:强制将实型10.6转换为整型后保存
  int a = (int)10.5;
}


数值类型和字符串类型之间转换

    package main
    import "fmt"
    func main() {
        var num1 int32 = 65
        // 可以将整型强制转换, 但是会按照ASCII码表来转换
        // 但是不推荐这样使用
        var str1 string = string(num1)
        fmt.Println(str1)

        var num2 float32 = 3.14
        // 不能将其它基本类型强制转换为字符串类型
        var str2 string = string(num2)
        fmt.Println(str2)

        var str3 string = "97"
        // 不能强制转换, cannot convert str2 (type string) to type int
        var num3  int = int(str3)
        fmt.Println(num3)
    }
  package main
  import "fmt"
  func main() {
      var num1 int32 = 10
      // 第一个参数: 需要被转换的整型,必须是int64类型
      // 第二个参数: 转换为几进制,  必须在2到36之间
      // 将32位十进制整型变量10转换为字符串,并继续保留10进制格式
      str1 := strconv.FormatInt(int64(num1), 10)
      fmt.Println(str1) // 10
      // 将32位十进制整型变量10转换为字符串,并转换为2进制格式
      str2 := strconv.FormatInt(int64(num1), 2)
      fmt.Println(str2) // 1010

      var num5 float64 = 3.1234567890123456789
      // 第一个参数: 需要转换的实型, 必须是float64类型
      // 第二个参数: 转换为什么格式,f小数格式, e指数格式
      // 第三个参数: 转换之后保留多少位小数, 传入-1按照指定类型有效位保留
      // 第四个参数: 被转换数据的实际位数,float32就传32, float64就传64
      // 将float64位实型,按照小数格式并保留默认有效位转换为字符串
      str3 := strconv.FormatFloat(num5, 'f', -1, 64)
      fmt.Println(str3) // 3.1234567
      str4 := strconv.FormatFloat(num5, 'f', -1, 64)
      fmt.Println(str4) // 3.1234567890123457
      // 将float64位实型,按照小数格式并保留2位有效位转换为字符串
      str5 := strconv.FormatFloat(num5, 'f', 2, 64)
      fmt.Println(str5) // 3.12
      // 将float64位实型,按照指数格式并保留2位有效位转换为字符串
      str6 := strconv.FormatFloat(num5, 'e', 2, 64)
      fmt.Println(str6) // 3.12

      var num6 bool = true
      str7 := strconv.FormatBool(num6)
      fmt.Println(str7) // true
  }
  package main
  import "fmt"
  func main() {
      var str1 string = "125"
      // 第一个参数: 需要转换的数据
      // 第二个参数: 转换为几进制
      // 第三个参数: 转换为多少位整型
      // 注意点: ParseInt函数会返回两个值, 一个是转换后的结果, 一个是错误
      // 如果被转换的数据转换之后没有超出指定的范围或者不能被转换时,
      // 那么错误为nil, 否则错误不为nil
      // 将字符串"125"转换为10进制的int8
      num1, err := strconv.ParseInt(str1, 10, 8)
      if err != nil {
          fmt.Println(err)
      }
      fmt.Println(num1)

      var str2 string = "150"
      // 将字符串"150"转换为10进制的int8
      // 由于int8的取值范围是-128~127, 所以转换之后超出了指定的范围, error不为nil
      num2, err := strconv.ParseInt(str2, 10, 8)
      if err != nil {
          fmt.Println(err)
      }
      fmt.Println(num2)

      var str3 string = "3.1234567890123456789"
      // 第一个参数: 需要转换的数据
      // 第二个参数: 转换为多少位小数, 32 or 64
      // ParseFloat同样有两个返回值, 如果能够正常转换则错误为nil, 否则不为nil
      num3, err := strconv.ParseFloat(str3, 32)
      if err != nil {
          // 例如: 把字符串"3.14abc"转换为小数就会报错, 因为"3.14abc"不是一个小数
          fmt.Println(err)
      }
      fmt.Println(num3)

      var str4 string = "true"
      // 第一个参数: 需要转换的数据
      // ParseBool同样有两个返回值, 如果能够正常转换则错误为nil, 否则不为nil
      num4, _ := strconv.ParseBool(str4)
      fmt.Println(num4)
  }
    package main
    import "fmt"
    func main() {
        var str1 string = "abc"
        num1, _ := strconv.ParseInt(str1, 10, 32)
        fmt.Println(num1) // 0

        num2, _ := strconv.ParseFloat(str1, 32)
        fmt.Println(num2) // 0

        num3, _ := strconv.ParseBool(str1)
        fmt.Println(num3) // false
    }
   package main
   import "fmt"
   func main() {
       var num1 int32 = 110
       // 快速将整型转换为字符串类型
       // 注意:Itoa方法只能接受int类型
       var str1 string = strconv.Itoa(int(num1))
       fmt.Println(str1)

       var str2 string = "666"
       // 快速将字符串类型转换为整型
       // 注意: Atoi方法返回两个值, 一个值是int,一个值是error
       // 如果字符串能被转换为int,那么error为nil, 否则不为nil
       num2, err := strconv.Atoi(str2)
       if err != nil{
           fmt.Println(err)
       }
       fmt.Println(num2)
   }
  package main
  import "fmt"
  func main() {
      var num1 int32 = 110
      // Sprintf函数和Printf函数很像, 只不过不是输出而将格式化的字符串返回给我们
      var str1 string = fmt.Sprintf("%d", num1)
      fmt.Println(str1)

      var num2 float32 = 3.14
      var str2 string = fmt.Sprintf("%f", num2)
      fmt.Println(str2)

      var num3 bool = true
      var str3 string = fmt.Sprintf("%t", num3)
      fmt.Println(str3)
  }

Go语言常量



 enum 枚举名 {
    枚举元素1,
    枚举元素2,
    … …
 };

const(
  枚举元素1 = iota
  枚举元素2 = iota
  ... ...
)
上一篇 下一篇

猜你喜欢

热点阅读