您的位置:首页 > 财经 > 金融 > 排名查询_设计网站一般要多少钱_seo如何优化网站推广_腾讯朋友圈广告代理

排名查询_设计网站一般要多少钱_seo如何优化网站推广_腾讯朋友圈广告代理

2024/11/16 17:27:11 来源:https://blog.csdn.net/ZunXin_2580/article/details/143645018  浏览:    关键词:排名查询_设计网站一般要多少钱_seo如何优化网站推广_腾讯朋友圈广告代理
排名查询_设计网站一般要多少钱_seo如何优化网站推广_腾讯朋友圈广告代理

1. 字面量

字面量,按照计算机科学的术语来讲是用于表达源代码中一个固定值的符号,也叫字面值。两个叫法都是一个意思,写了什么东西,值就是什么,值就是“字面意义上“的值。

1.1 整型字面量

为了便于阅读,允许使用下划线_来进行数字划分,但是仅允许在前缀符号之后数字之间使用。

24 // 24
2_4 // 24
0_2_4 // 24
10_000 // 10k
100_000 // 100k
0O24 // 20
0b00 // 0
0x00 // 0
0x0_0 // 0

1.2 浮点数字面量

通过不同的前缀可以表达不同进制的浮点数

0.
72.40
072.40       // == 72.40
2.71828
1.e+0
6.67428e-11
1E6
.25
.12345E+5
1_5.         // == 15.0
0.15e+0_2    // == 15.00x1p-2       // == 0.25
0x2.p10      // == 2048.0
0x1.Fp+0     // == 1.9375
0X.8p-0      // == 0.5
0X_1FFFP-16  // == 0.1249847412109375
0x15e-2      // == 0x15e - 2 (integer subtraction)

1.3 复数字面量

0i
0123i         // == 123i
0o123i        // == 0o123 * 1i == 83i
0xabci        // == 0xabc * 1i == 2748i
0.i
2.71828i
1.e+0i
6.67428e-11i
1E6i
.25i
.12345E+5i
0x1p-2i       // == 0x1p-2 * 1i == 0.25i

1.4 字符字面量

字符字面量必须使用单引号括起来'',Go中的字符完全兼容utf8

'a'
'ä'
'你'
'\t'
'\000'
'\007'
'\377'
'\x07'
'\xff'
'\u12e4'
'\U00101234'

1.5 转义字符

Go中可用的转义字符

\a   U+0007 响铃符号(建议调高音量)
\b   U+0008 回退符号
\f   U+000C 换页符号
\n   U+000A 换行符号
\r   U+000D 回车符号
\t   U+0009 横向制表符号
\v   U+000B 纵向制表符号
\\   U+005C 反斜杠转义
\'   U+0027 单引号转义 (该转义仅在字符内有效)
\"   U+0022 双引号转义 (该转义仅在字符串内有效)

1.6 字符串字面量

字符串字面量必须使用双引号""括起来或者反引号(反引号字符串不允许转义)

`abc`                // "abc"
`\n
\n`                  // "\\n\n\\n"
"\n"
"\""                 // `"`
"Hello, world!\n"
"今天天气不错"
"日本語"
"\u65e5本\U00008a9e"
"\xff\u00FF"

1.7 Code

package mainimport "fmt"/*
字面量
*/
func main() {// 整数var a = 100_000var b = 0b00var c = 0x00fmt.Println(a, b, c)// 浮点var d = 0.fmt.Println(d)// 复数var e = 0ivar f = .25ifmt.Println(e, f)
}

2. 风格

关于编码风格这一块Go是强制所有人统一同一种风格,Go官方提供了一个格式化工具gofmt,通过命令行就可以使用,该格式化工具没有任何的格式化参数可以传递,仅有的两个参数也只是输出格式化过程,所以完全不支持自定义,也就是说所有通过此工具的格式化后的代码都是同一种代码风格,这会极大的降低维护人员的心智负担,所以在这一块追求个性显然是一个不太明智的选择。

下面会简单列举一些规则,平时在编写代码的时候也可以稍微注意一下。

  1. 花括号,关于花括号{}到底该不该换行,几乎每个程序员都能说出属于自己的理由,在Go中所有的花括号都不应该换行。
// 正确示例
func main() {fmt.Println("Hello 世界!")
}// 错误示例
func main() 
{fmt.Println("Hello 世界!")
}
  1. 缩进,Go默认使用tabs也就是制表符进行缩进,仅在一些特殊情况会使用空格。

  2. 间隔,Go中大部分间隔都是有意义的,从某种程度上来说,这也代表了编译器是如何看待你的代码的,例如下方的数学运算

    2*9 + 1/3*2
    

    众所周知,乘法的优先级比加法要高,在格式化后,*符号之间的间隔会显得更紧凑,意味着优先进行运算,而+符号附近的间隔则较大,代表着较后进行运算。

  3. 还是花括号,花括号在任何时候都不能够省略,就算是只有一行代码,例如

    // 正确示例
    if a > b {a++
    }
    // 错误示例
    if a > b a++
    

3. 常量

常量的值无法在运行时改变,一旦赋值过后就无法修改,其值只能来源于:

  • 字面量
  • 其他常量标识符
  • 常量表达式
  • 结果是常量的类型转换
  • iota

常量只能是基本数据类型,不能是

  • 除基本类型以外的其它类型,如结构体,接口,切片,数组等
  • 函数的返回值

常量的值无法被修改,否则无法通过编译

3.1 初始化

常量的声明需要使用 const 关键字,常量需要在声明时就初始化一个值,并且常量的类型可以省略

const a = "张三"
const num byte = 1
const bExpression = (1+2+3)/2%100 + num
fmt.Println(a, num, bExpression) // 张三 1 4

如果仅仅只是声明而不确定值,将会无法通过编译

在这里插入图片描述

编译器报错

missing init expr for b

在Go中,可以批量声明变量并赋值,定义常量或者变量时都没有问题

const (name = "张三"age  = 13
)
const c,d,e = 1,"老吴",false

在同一个常量分组中,在已经赋值的常量后面的常量可以不用赋值,其值默认就是前一个的值,比如

const (A = 1B // 1C // 1D // 1E // 1
)

3.2 iota

iota是一个内置的常量标识符,通常用于表示一个常量声明中的无类型整数序数,一般都是在括号中使用。

const iota = 0 

看几个使用案例

const (Num = iota // 0Num1 // 1Num2 // 2Num3 // 3Num4 // 4
)

也可以这么写

const (Num = iota*2 // 0Num1 // 2Num2 // 4Num3 // 6Num4 // 8
)

还可以

const (Num = iota << 2*3 + 1 // 1Num1 // 13Num2 // 25Num3 = iota // 3Num4 // 4
)

通过上面几个例子可以发现,iota是递增的,第一个常量使用iota值的表达式,根据序号值的变化会自动的赋值给后续的常量,直到用新的iota重置,这个序号其实就是代码的相对行号,是相对于当前分组的起始行号,看下面的例子

const (Num  = iota<<2*3 + 1 // 1 第一行Num2 = iota<<2*3 + 1 // 13 第二行_ // 25 第三行Num3 //37 第四行Num4 = iota // 4 第五行_ // 5 第六行Num5 // 6 第七行
)

例子中使用了匿名标识符_占了一行的位置,可以看到iota的值本质上就是iota所在行相对于当前const分组的第一行的差值。而不同的const分组则相互不会影响

3.3 枚举

Go 语言没有位枚举单独设计一个数据类型,不像其他语言通常会有一个enum来表示。一般在Go中,都是通过自定义类型+const+iota来实现枚举

type season bytefunc main() {const (Spring season = iotaSummerAutumnWinter)
}

这些枚举实际上就是数字,Go也不支持直接将其转换为字符串,但我们可以通过给自定义类型添加方法来返回其字符串表现形式,实现Stringer接口即可。

func (s Season) Test() string {switch s {case Spring:return "spring"case Summer:return "summer"case Autumn:return "autumn"case Winter:return "winter"}return ""
}

这样一来就是一个简单的枚举实现了。你也可以通过官方工具Stringeropen in new window来自动生成枚举。

不过它有以下缺点:

  • 类型不安全,因为Season是自定义类型,可以通过强制类型转换将其他数字也转换成该类型

    Season(6)
    
  • 繁琐,字符串表现形式需要自己实现

  • 表达能力弱,因为const仅支持基本数据类型,所以这些枚举值也只能用字符串和数字来进行表示

4. 变量

变量是用于保存一个值的存储位置,允许其存储的值在运行时动态的变化。每声明一个变量,都会为其分配一块内存以存储对应类型的值

4.1 声明

在go中的类型声明是后置的,变量的声明会用到var关键字,格式为var 变量名 类型名,变量名的命名规则必须遵守标识符的命名规则

package mainimport "fmt"var intNum int
var str string
var char byte/*
变量的定义
*/
func main() {var i int = 15i = 10fmt.Print(i)
}

在go语言中,变量的定义是以 var 变量名 数据类型 = 值 来确定的。

把它看作是强制规定数据类型的js语法就可以了

注意事项:

  1. 变量表示内存中的一个存储区域

  2. 该区域有自己的名称(变量名)和类型(数据类型)

  3. Golang变量使用的三种方式

    1. 指定变量类型,声明后如果不赋值,使用默认值

      int 数据结构 的默认值是 0

    2. 根据值自行判定变量类型(类型推导)

      var num = 12
      var str = "demo1"
      fmt.Print(num, "\n", str)
      

      跟 JS 语法差不多,使用var 可以让go语言自行推导值是什么数据类型

    3. 省略var,注意:=左侧的变量不应该是已经声明过的,否则会导致编译错误

      name := "tom"
      fmt.Print("name is ? ", name)
      

      := 这种省略方式,等价于 var name string name = “tom”

  4. 多变量声明

    在编程中,有时我们需要一次性声明多个变量,Golang也提供这样的语法

    var n1, n2, n3 int
    fmt.Print("n1=", n1, "n2=", n2, "n3=", n3)var name, age, sex = "张三", "18", "男"
    fmt.Print("name=", name, "age=", age, "sex=", sex)name1, age1, sex1 := "张三", "18", "男"
    fmt.Print("name=", name1, "age=", age1, "sex=", sex1)
    
  5. 定义全局变量

    在这里插入图片描述

    同时,当要声明多个不同类型的变量时,可以使用()进行包裹,可以存在多个()

    var (address = "湖南"father  = "老刘"son     = "老八"
    )
    var (name    stringage     intaddress string
    )var (school stringclass int
    ) 
    fmt.Print(address, father, son)
    

    当要声明多个相同类型的变量时,可以只写一次类型

    var numA, numB, numC int
    
  6. 该区域的数据值可以在同一类型范围内不断变化

  7. 变量在同一作用域内不能重名

  8. 变量=变量名+值+数据类型

  9. Go的变量如果没有赋予初始值,编译器会使用默认值,比如int默认值0,string默认值为空

  10. 一个变量如果只是声明而不赋值,那么变量存储的值就是对应类型的零值

4.2 赋值

赋值会用到运算符=,例如

var name string
name = "jack"

也可以声明的时候直接赋值

var name string = "jack"

或者这样也可以

var name string
var age int
name, age = "jack", 1

第二种方式每次都要指定类型,可以使用官方提供的语法糖:短变量初始化,可以省略掉var关键字和后置类型,具体是什么类型交给编译器自行推断。

name := "jack" // 字符串类型的变量。

虽然可以不用指定类型,但是在后续赋值时,类型必须保持一致,下面这种代码无法通过编译。

a := 1
a = "123"// 报错
// cannot use "123" (untyped string constant) as int value in assignment

还需要注意的是,短变量初始化不能使用nil,因为nil不属于任何类型,编译器无法推断其类型。

name := nil // 无法通过编译

短变量声明可以批量初始化

name, age := "jack", 1

短变量声明方式无法对一个已存在的变量使用,因为它本身所代表的就是 var a int = 1,多次使用就代表重复声明一个变量

// 错误示例
var a int
a := 1// 错误示例
a := 1
a := 2

但是有一种情况除外,那就是在赋值旧变量的同时声明一个新的变量,比如

a := 1
a, b := 2, 2

这种代码是可以通过编译的,变量a被重新赋值,而b是新声明的。

在go语言中,有一个规则,那就是所有在函数中的变量都必须要被使用,比如下面的代码只是声明了变量,但没有使用它。那么在编译时就会报错,提示你这个变量声明了但没有使用

func main() {a := 1
}
// a declared and not used

这个规则仅适用于函数内的变量,对于函数外的包级变量则没有这个限制,下面这个代码就可以通过编译。

var a = 1func main() {}

4.3 匿名

用下划线可以表示不需要某一个变量

Open(name string) (*File, error)

比如os.Open函数有两个返回值,你不需要某一个变量时,就可以使用下划线_代替

func main() {a := "张三变量"// 当test方法有两个返回值,想要不接收哪个值就可以使用 下划线_ 来舍弃它c, _ := test(a)fmt.Println(c)
}func test(str string) (string, bool) {fmt.Println(str)str += " 进行了修改"return str, false
}

4.4 变换

在Go中,如果想要交换两个变量的值,不需要使用指针,可以使用赋值运算符直接进行交换,语法上看起来非常直观,例子如下

num1, num2 := 25, 36
num1, num2 = num2, num1

思考下面这一段代码,这是计算斐波那契数列的一小段代码,三个变量在计算后的值分别是什么

a, b, c := 0, 1, 1
a, b, c = b, c, a+b// 答案: 1 1 1

为什么不是 1 1 2 呢?

明明a已经被赋予b的值了,为什么a+b的结果还是1?go在进行多个变量赋值运算时,它的顺序是先计算值再赋值,并非从左到右计算。

a, b, c = b, c, a+b
// a, b, c = 1, 1, 0+1

4.5 比较

变量之间的比较有一个大前提,那就是它们之间的类型必须相同,go语言中不存在隐式类型转换,像下面这样的代码是无法通过编译的

func main() {var a uint64var b int64// 编译器会告诉你两者之间类型并不相同// 错误:invalid operation: a == b (mismatched types uint64 and int64)fmt.Println(a == b) 
}

在没有泛型之前,早期go提供的内置minmax函数只支持浮点数,到了1.21版本,go才终于将这两个内置函数用泛型重写,现在可以使用min函数比较最小值、使用max函数比较最大值

minVal := min(1, 2, -1, 1.2)
maxVal := max(100, 22, -1, 1.12)

它们的参数支持所有的可比较类型,go中的可比较类型有

  • 布尔
  • 数字
  • 字符串
  • 指针
  • 通道 (仅支持判断是否相等)
  • 元素是可比较类型的数组(切片不可比较)
  • 字段类型都是可比较类型的结构体(仅支持判断是否相等)

除此之外,还可以通过导入标准库cmp来判断,不过仅支持有序类型的参数,在go中内置的有序类型只有数字和字符串。

import "cmp"func main() {cmp.Compare(1, 2)cmp.Less(1, 2)
}

4.6 代码块

在函数内部,可以通过花括号建立一个代码块,代码块彼此之间的变量作用域是相互独立的。例如下面的代码

func main() {a := 1{a := 2fmt.Println(a)}{a := 3fmt.Println(a)}fmt.Println(a)
}

它输出的顺序:2 3 1

块与块之间的变量相互独立,不受干扰,无法访问,但是会受到父块中的影响

func main() {a := 1{a := 2fmt.Println(a)}{fmt.Println(a)}fmt.Println(a)
}

它的输出的顺序:2 1 1

5. 类型强转

5.1 整型

Go 和 java/c 不同,Go在不同类型的变量之间赋值需要显式转换,也就是说Go中数据类型不能自动转换

在Go中的强制转换会有对应类型的标准函数 例如:int类型 有 int()函数,来转换数据类型 var c int = int(u)

/*
强制类型转换
*/
func main() {var i int = 2var f float64 = float64(i)var u uint = uint(f)fmt.Println(i, f, u)
}

在Go中,低精度 转——》搞精度 没有问题,但是 高精度 转——》低精度,虽然编译不会报错,但是转换出来的结果是按溢出处理,和希望的结果不一样

var num1 int64 = 9999999
var num2 int8 = int8(num1)
fmt.Println(num2) // 127
  • Go中,数据类型的转换可以从 表示范围小》表示范围大,也可以 范围大》范围小
  • 被转换的是变量存储的数据(值),变量本身的数据类型并没有变化

5.1.1 练习一

在这里插入图片描述

func main() {var n1 int32 = 12var n2 int64var n3 int8n2 = n1 + 20 // n2 类型不一致n3 = n1 + 20fmt.Println(n1, n2, n3)
}

当类型不同时,接受变量的数据类型也必须一直,否则如上图报错

5.2.1 练习二

var n1 int32 = 12
var n2 int8
var n3 int8n2 = int8(n1) + 127 // 编译通过,但是会发生溢出
n3 = int8(n1) + 128 // 内存超出上限,直接报错
fmt.Println(n3, n2)

5.2 string 字符串

在程序开发中,我们经常需要将基本类型转成string类型或者string转基本数据类型

占位符名表示
%d十进制整数
%f浮点数(默认保留六位小数)
%s字符串
%t布尔型
%b二进制数
%o八进制数
%x小写十六进制数
%X大写十六进制数
%qASCII 转 字符
%cASCII 转 字符串(去引号)

5.2.1 方法一:fmt.Sprintf(“%参数”,表达式)

  • 参数需要和表达式的数据类型相匹配
  • fmt.Sprintf()… 会返回转换后的字符串
var str string
var num1 int = 10
var num2 float64 = 123.345
var b bool = true
var c byte = 'a'str = fmt.Sprintf("%d", num1)
fmt.Println("int 转 string:", str)str = fmt.Sprintf("%f", num2)
fmt.Println("float64 转 string:", str)str = fmt.Sprintf("%t", b)
fmt.Println("bool 转 string:", str)str = fmt.Sprintf("%q", c)
fmt.Println("byte 转 string:", str)str = fmt.Sprintf("%c", c)
fmt.Println("byte 转 string(去引号):", str)

5.2.2 方法二:strconv

var str string
var num1 int = 10
var num2 float64 = 123.345
var b bool = true
//var c byte = 'a'str = strconv.FormatInt(int64(num1), 10)
fmt.Println("int 转 string:", str)
/*参数一:转换的变量参数二: 'f' 代表转换的格式参数三:表示保留小数位个数参数四:表示这个小数是float64
*/
str = strconv.FormatFloat(num2, 'f', -1, 64)
fmt.Println("float64 转 string:", str)str = strconv.FormatBool(b)
fmt.Println("bool 转 string:", str)

5.2.3 string转基本数据类型

var b bool
var strBool string = "true"
// ParseBool(value bool,err error) 方法返回两个值,第二个返回值隐藏掉就可以了
b, _ = strconv.ParseBool(strBool)
fmt.Println("字符串转bool:", b)var n1 int
var n2 int64
var strInt string = "12138"
// ParseInt(value int64,err error)也是返回两个值,但是它返回的整型是int64类型,如果想要其他类型必须根据接收的变量然后再转一次
n2, _ = strconv.ParseInt(strInt, 10, 64)
n1 = int(n2)
fmt.Println(n1)var strFloat string = "123.345"
var f1 float64
f1, _ = strconv.ParseFloat(strFloat, 64)
fmt.Println(f1)

5.2.4 注意

当转换不成功时,转换后的结果会是那个类型的默认值

var str4 string = "hello"
var n3 int64 = 11
n3, _ = strconv.ParseInt(str4, 10, 64)
fmt.Println(n3)// 0

6. 运算符

下面是Go语言中支持的运算符号的优先级排列

Precedence    Operator5             *  /  %  <<  >>  &  &^4             +  -  |  ^3             ==  !=  <  <=  >  >=2             &&1             ||

有一点需要稍微注意下,go语言中没有选择将~作为取反运算符,而是复用了^符号,当两个数字使用^时,例如a^b,它就是异或运算符,只对一个数字使用时,例如^a,那么它就是取反运算符。go也支持增强赋值运算符,如下。

a += 1
a /= 2
a &^= 2

在Go语言中,没有自增和自减运算符,它们被降级为了语句statement并且规定了只能位于操作数的后方,所以不用再去纠结 i++ 和 ++i 这样的蠢问题(个人意见)。

a++ // 正确
++a // 错误
  • 另外,当使用 a++ 这样的语法时,它们将不再具有返回值

    意思是说 a = b++ 这种语法是错误的。

6.1 取反运算符

func main() {var a int = 2a = ^afmt.Println(a) // -3
}

在Go中,整数是用补码表示的,对于一个有符号整数a,其按位取反的结果是 -x -1

6.2 其他的运算

至于其他的运算符本文就不多说了,因为与其他编程语言差异不大

i := 1
j := 2
c := i + j
c = i*j
c = i/j
c = i%j
....

7. 😍前篇知识回顾

  1. Go的环境安装与开发工具配置
  2. Go的运行流程步骤与包的概念

8. 💕👉 其他好文推荐

  • 还不了解Git分布式版本控制器?本文将带你全面了解并掌握
  • 带你认识Maven的依赖、继承和聚合都是什么!有什么用?
  • 2-3树思想与红黑树的实现与基本原理
  • !全网最全! ElasticSearch8.7 搭配 SpringDataElasticSearch5.1 的使用
  • 全面深入Java GC!!带你完全了解 GC垃圾回收机制!!
  • 全面了解Java的内存模型(JMM)!详细清晰!
  • 在JVM中,类是如何被加载的呢?本篇文章就带你认识类加载的一套流程!

全文资料学习全部参考于:Golang中文学习文档

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com