Primitive Types in Go

Introduction

As a strong  type static language, Go has many primitive types we will care about. In first level, they can be divided into two groups: non-collection and collections(e.g. array, slice, map). In this article we will talk three different non-collection primitive types in Go.

1. Boolean

2. Numerical (integer, float and complex number)

3. Text (string and rune)

Boolean

1. Use true and false for boolean

This may sounds crystal forward, but in Go we can only use keywords true & false for boolean type. Not like in some other language we can use 3 or 11 or 19 for true, 0 for false.

For example:

func main() {
      r := 36
      for 3 {
          fmt.Printf("%v, %T\n", r, r)
      }
}
// output
// prog.go:9:2: non-bool 3 (type untyped number) used as for condition   

Numerical 

1. Integer

a) Interger can be sign interger or unsign interger

sign integers, there are 5 versions:
  int: has varying size, but mininal int32.
  int8: -128 ~ 127
  int16: -32,768 ~ 32,767
  int32: around 2 billion
  int64: vary large
  use big package from math library can set more larger number

unsign integer, there are four versions:
  uint, uint8, uint16, uint32, we don‘t have int64.

b) calculations

There are five kinds of calculation we can do in integer: add, substract, multiple, divise, remainder(remainder only exist in integer)

Integer calculation will result integer, the remainder will miss. We can use % operator to get remainder between integers.

func main() {
	a := 3
	b := 10
	fmt.Println(b / a)
	fmt.Println(b % a)
}
// output
// 3, remainder is missing
// 1, get remainder using % operator

Notice integers in same family but with different type can not do caculateion. e.g. int8 + int16 = error

c) bitwise calculations
To keep thing simple, we don‘t cover bitwise calculations for now.

2.Floating points

a) There are two version of floating points, float32 and float64.

We can use decimal(e.g. 3.14) or exponential(3.14e12, or 3.14E12).

func main() {
	a := 10.1
	b := 10.1E12
	fmt.Printf("%v, %T\n", a, a)
	fmt.Printf("%v, %T", b, b)
}
// output
// 10.1, float64
// 1.01e+13, float64

b) calculations

Except %(remainder operator), they are: add, substract, multiple, divise. And floating points don‘t have bitwise calculation.

3. complex number

There are not so much language design complex number as a build-in type. From this we can get a glimps of how powerful Go is in science.

a) two versions, complex64 and complex128.

In math, we use float + float i to represent a complex number. So complex number is float32 + float32 = complex64 or float64 + float64 = complex128

func main() {
	a := 1 + 2i
	b := complex(1, 1.2)
	fmt.Printf("%v, %T\n", a, a)
	fmt.Printf("%v, %T", b, b)
}
// output
// (1+2i), complex128
// (1+1.2i), complex128

b) build-in functions

complex() to build a complex number.

real() to get the real part of a complex number.

imag() to get the imaginary part of a complex number.

func main() {
	a := 1 + 2i
	b := complex(1, 1.2)
	fmt.Printf("%v, %T\n", a, a)
	fmt.Printf("%v, %T\n", b, b)
	fmt.Printf("%v, %T\n", real(b), real(b))
	fmt.Printf("%v, %T\n", imag(b), imag(b))
}
// output
// (1+2i), complex128
// (1+1.2i), complex128
// 1, float64
// 1.2, float64

c) calculations

They are: add, substract, multiple, divise. Notice, in math, multiplication and division of two complex number is defined as polynomial style.

Text

1. string

String in Go stands for any utf8 character. It‘s powerful but also makes string can not encode all character available(for that, we have rune).

a) string, collection of letters

String behaves sort of like an array. That is, a collection of letters. We can use [] operator to slice them.

func main() {
	s := "This is a string"
        fmt.Printf("%v, %T", s[2], s[2])
}
// output
// 105, uint8

This result is out of our expect. We are expecting a letter "i". Actually, when we slice a string, in other language we may can get letters, in Go we will get the number of utf8/ ascii code. 105 stands for "i" in uft8/ ascii. And uint8  is alias for byte in Go.

We can use string() to change it back to a string.

func main() {
	s := "This is a string"
        fmt.Printf("%v, %T", string(s[2]), string(s[2]))
}
// output
// i, string

b) string is immutable

Although a string can be slice like an array, but we can‘t change the value inside.

func main() {
        s := "This is a string"
        s[2] = "u"
        fmt.Printf("%v, %T", string(s[2]), s[2])
}
// two errors:
// first, can not assign a string "u" to  byte s[2]
// second, can not manipulate the value inside a string

c) concat two string with +

A most common task is to concat two string together, in Go we can use operator +.

func main() {
	s := "This is a string"
	s2 := "This is also a string"
        fmt.Println(s + s2)
}
// output
// This is a stringThis is also a string

d) convert string to collection of byte

We can use []byte() to conver a string to collection of bytes. This can make our application work more easily with other applications than we only use string.

func main() {
	s := "This is a string"
	b := []byte(s)
        fmt.Printf("%v, %T", b, b)
}
// output
// [84 104 105 115 32 105 115 32 97 32 115 116 114 105 110 103], []uint8

The result shows a collection of integer numbers, that is ascii/utf8 value for each letter and space in our string s. As we said before, uint8 is alias for byte, so this []uint8 means []byte.

We can exchange []byte and string back and forward as we need without any effort. In some situation, we may say string is collection of byte([]byte), and vice versa.

func main() {
	s := "This is a string"
	b := []byte(s)
        fmt.Printf("%v, %T\n", b, b)
	fmt.Printf("%v, %T", string(b), string(b))
}
// output
// [84 104 105 115 32 105 115 32 97 32 115 116 114 105 110 103], []uint8
// This is a string, string

2.rune

a) use single quote to declare a rune

In Go, we use double quote " to declare a string and use single quote ‘ to decalre a rune.

A rune can only be one character. var r rune = ‘aa‘ will return error.

func main() {
	var r rune = ‘a‘
	r2 := ‘a‘
	fmt.Printf("%v, %T\n", r, r)
	fmt.Printf("%v, %T", r2, r2)
}
// output
// 97, int32
// 97, int32

In the result we can see the type is int32, that means rune is alias for int32.

b) why we need rune

Slicing a string may result wrong when it is not an english string.

As we can see in the first for-loop, each s[i] is a uint8(byte). That is, out application recognize Chinese character(hanzi) as english letter. But each Chinese character is 3 bytes not 1 byte(english letter). So the second for-loop output completely wrong.

func main() {
	var s string = "劳动光荣"
	b := []byte(s)
	fmt.Printf("%v, %T\n", b, b)
	fmt.Printf("%v, %T\n", string(b), string(b))

	for i := 0; i < len(s); i++ {
		fmt.Printf("%v, %T\n", s[i], s[i])
	}

	for i := 0; i < len(s); i++ {
		fmt.Printf("%v, %T\n", string(s[i]), string(s[i]))
	}
}
// output
[229 138 179 229 138 168 229 133 137 232 141 163], []uint8
劳动光荣, string
229, uint8
138, uint8
179, uint8
229, uint8
138, uint8
168, uint8
229, uint8
133, uint8
137, uint8
232, uint8
141, uint8
163, uint8
å, string
?, string
³, string
å, string
?, string
¨, string
å, string
?, string
?, string
è, string
?, string
£, string

If we use rune, our application can recognize non-english character well. In for-loop, we have range function to get each rune of non-english character.

Each output of first for-loop is int32, which means rune.

func main() {
	var s string = "劳动光荣"
	for i, v := range s {
		fmt.Printf("%v, %v, %T\n", i, v, v)
	}

	for i, v := range s {
		fmt.Printf("%v, %v, %T\n", i, string(v), string(v))
	}
}
// output
0, 21171, int32
3, 21160, int32
6, 20809, int32
9, 33635, int32
0, 劳, string
3, 动, string
6, 光, string
9, 荣, string

  

Summary

To keep things simple, there are three notice from this article:

1. Can only use keyword true and false for boolen type.

2. Can not calculate different type number even they are in same family. That is int8 + int32 = error.

3. Care about non-english string, we might need help of rune.

原文地址:https://www.cnblogs.com/drvongoosewing/p/12040340.html

时间: 2024-08-29 19:45:25

Primitive Types in Go的相关文章

Java中的原始类型(Primitive Types)与引用类型(Reference Values)

Java虚拟机可以处理的类型有两种,一种是原始类型(Primitive Types),一种是引用类型(Reference Types). 与之对应,也存在有原始值(Primitive Values)和引用值(Reference Values)两种类型的数值可用于变量赋值.参数传递.方法返回和运算操作. 原始类型与值 Java虚拟机支持的原始数据类型包括数值类型.布尔类型和returnAddress类型. 数值类型包括:整数类型和浮点类型. 整数类型包括: 1.byte 2.short 3.int

Prefer Domain- Specific Types to Primitive Types

Prefer Domain- Specific Types to Primitive Types Einar Landre ON SEPTEMBER 23, 1999, the $327.6 million Mars Climate Orbiter was lost while entering orbit around Mars due to a software error back on Earth. The error was later called the metric mix-up

Primitive Types and Expressions

Class Data or Attributes state of the application Methods or Functions have behavior Namespace is a container for related classes Assembly (DLL or EXE) is a container for related namespaces is a file which can either be a EXE or  a DLL Application in

Oracle OCA J2SE7 Cetificate - Rules for Primitive Types

Any bigger than an int can NEVER be assigned to an int or anything smaller than int (byte, char, or short) without explicit cast. Constant values up to int can be assigned (without cast) to variables of lesser size (e.g. short to byte) if the values

C# 2012 step by step 学习笔记8 CHAPTER 9 Creating Value types with enumerations and Structures

C# 2012 step by step 学习笔记8 CHAPTER 9 Creating Value types with enumerations and Structures things about 1. Declare an enumeration type. 2. Create and use an enumeration type. 3. Declare a structure type. 4. Create and use a structure type. 5. Explain

.NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系.

.NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系. The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single. https://msdn.microsoft.com/zh-cn/library/s

Android jni/ndk编程二:jni数据类型转换(primitive,String,array)

一.数据类型映射概述 从我们开始jni编程起,就不可能避开函数的参数与返回值的问题.java语言的数据类型和c/c++有很多不同的地方,所以我们必须考虑当在java层调用c/c++函数时,怎么正确的把java的参数传给c/c++函数,怎么正确的从c/c++函数获取正确的函数返回值:反之,当我们在c/c++中使用java的方法或属性时,如何确保数据类型能正确的在java和c/c++之间转换. 回顾我们上一篇文章中的那个c函数: #include <stdio.h> #include <jn

Core Java Volume I — 3.3. Data Types

3.3. Data TypesJava is a strongly typed language(强类型语音). This means that every variable must have a declared type(每个变量都必须声明类型). There are eight primitive types in Java(Java有8种原始类型). Four of them are integer types; two are floatingpoint number types;

4.1 primitive and reference values

ECMAScript variables may contains two different types of data: primitive values and reference values. Primitive values are simple atomic pieces of data, while reference values are objects that may be made up of multiple values. The five primitive typ