【Go语言圣经3.6】

【Go语言圣经】从零开始学Go----1.入门篇 《Go语言圣经》读书笔记,完整知识点整理,从零开始学Golang 阅读详情

目标

概念

  1. 常量与变量的主要区别在于:
    • 不可变性:常量在声明后其值就固定下来,不能再被修改。这保证了程序运行时不会因意外修改而导致错误。
      • 使用不可变数据(例如数学常数 π)可以避免意外修改带来的问题
    • 编译期计算:常量表达式在编译期间就会被求值,这不仅减少了运行时的计算负担,还意味着许多在运行时可能出错的操作(比如除零、越界)都可以在编译阶段捕获。
  2. Go 中常量的潜在类型为布尔型、字符串或数字
  3. 无类型常量:在定义时没有显式指定类型的常量。比如写 3.14、0 或 "hello",这些数值或字符串常量在初始状态下没有固定的类型。
  4. 六种无类型常量:分别对应布尔、整数、字符(rune)、浮点数、复数和字符串。
  5. 无类型常量更高精度的运算:无类型常量在算术运算中拥有比具体类型(如 int 或 float64)更高的精度(可以看作有 256 位或更多位的精度);像 ZiB 或 YiB 这样超出任何内置整数类型范围的常量,也仍然可以参与运算(例如 YiB / ZiB),因为在编译期编译器会将它们按照数学上准确的值处理。

要点

常量声明

  1. 声明常量时,可以直接赋予初值:

    
    const pi = 3.14159 // 近似值;实际上 math.Pi 提供了更精确的值
    

    这和变量声明语法类似,但常量的值一旦设定就不能修改。

  2. 批量声明常量

    多个相关常量可以使用小括号一起声明:

    const (
        e  = 2.71828182845904523536028747135266249775724709369995957496696763
        pi = 3.14159265358979323846264338327950288419716939937510582097494459
    )
    
    

    这样的批量声明不仅代码更简洁,也可以利用类型推断:如果没有显式指定类型,常量的类型会根据右侧的表达式自动推断。

    类型推断说明

    • 如果你在常量声明时没有显式标明类型,则 Go 会根据右边的表达式推断类型。例如:

      const timeout = 5 * time.Minute
      

      此时 timeout 会被推断为 time.Duration 类型,因为 time.Minute 本身是 time.Duration 类型的常量。

编译期常量表达式与优化

在数组定义中,可以用常量来指定数组的长度:

const IPv4Len = 4

func parseIPv4(s string) IP {
    var p [IPv4Len]byte
    // 解析 IPv4 地址的逻辑
}

这样,数组长度在编译期间就确定下来了。程序运行时减少了不必要的计算,提高了效率。

iota常量生成器

  1. iota的基本原理

    • 自动递增:在一个 const 声明块中,iota 是一个预定义标识符,它在第一行被置为 0,后续每出现一行常量声明,它的值自动加 1。
    • 省略初始化表达式:如果在常量声明块中,后面的常量省略了右侧的表达式,那么它们将默认使用前一行的表达式。这样在简单的复制中,虽然没有太大实用价值,但在配合 iota 时可以生成有规律的值。
  2. 例子

    type Weekday int
    
    const (
        Sunday Weekday = iota  // 0
        Monday                 // 1
        Tuesday                // 2
        Wednesday              // 3
        Thursday               // 4
        Friday                 // 5
        Saturday               // 6
    )
    
    

    这种方式使得常量的赋值变得简单且易于维护。

  3. iota 还常用于生成一系列位掩码(bit mask)

    type Flags uint
    
    const (
        FlagUp Flags = 1 << iota      // 1 << 0 = 1 (第 0 位)
        FlagBroadcast                 // 1 << 1 = 2 (第 1 位)
        FlagLoopback                  // 1 << 2 = 4 (第 2 位)
        FlagPointToPoint              // 1 << 3 = 8 (第 3 位)
        FlagMulticast                 // 1 << 4 = 16 (第 4 位)
    )
    
    

    每个常量都代表一个单独的 bit 位,这样在设置或测试标志时,可以使用位运算:

    • 测试标志:v & FlagUp == FlagUp
    • 清除标志:v &^= FlagUp —— 把 v 中与 FlagUp 对应的那一位变成 0(不管原来是1还是0)。这样就清除了这个标志。
    • 设置标志:v |= FlagBroadcast —— 把 v 中与 FlagBroadcast 对应的那一位变成1(即使之前是0)
  4. 利用 iota 生成一系列以 1024 为底的幂(例如 KiB、MiB 等)

    const (
        _ = 1 << (10 * iota)
        KiB // 1 << 10 = 1024
        MiB // 1 << 20 = 1048576
        GiB // 1 << 30 = 1073741824
        TiB // 1 << 40 = 1099511627776
        PiB // 1 << 50 = 1125899906842624
        EiB // 1 << 60 = 1152921504606846976
        // ZiB, YiB 等可能会超过某些平台的位数限制
    )
    
    

    通过这种方式,编译器自动计算出每一项的值,而无需手动写出复杂的计算。

  5. 局限性

    不能产生任意的幂:例如,要生成 1000、1000000 等(通常用于 KB、MB 等),因为 Go 语言没有内置的幂运算符(如 ** 或 pow),所以不能直接利用 iota 来生成 10 的幂。

无类型常量的灵活性:隐式转换

当你将无类型常量赋值给一个变量时,Go 编译器会根据上下文自动推断出一个“默认类型”。例如:

  • var x float64 = math.Pi
    这里,math.Pi 是一个无类型浮点常量,赋值时自动转换成 float64。

  • 又如:

    
    i := 0      // 隐式为 int 类型
    f := 0.0    // 隐式为 float64 类型
    c := 0i     // 隐式为 complex128 类型
    r := '\000'// 隐式为 rune(int32)类型
    
    

    对于一个没有显式类型的变量声明(包括简短变量声明),常量的形式将隐式决定变量的默认类型,

这种机制让我们在书写表达式时更灵活,无需反复写类型转换代码。

隐式转换与默认类型

当无类型常量出现在需要具体类型的上下文时(比如当一个无类型的常量被赋值给一个变量的时候),编译器会自动进行转换。例如:

var f float64 = 3 + 0i // 这里 3+0i 是无类型复数,但可以隐式转换为 float64

这种转换类似于在后台写了:

var f float64 = float64(3 + 0i)

注意: 转换要求目标类型必须能表示原始常量的值。如果值太大或不适合,则会导致编译错误。例如:

  • 将一个超出 int32 范围的无类型整数转换为 int32,会报错;
  • 将一个超出 float64 表示范围的浮点数转换为 float64,同样会报错。

无类型常量隐式转换的更多例子

var f float64 = 212
fmt.Println((f - 32) * 5 / 9)     // 输出 "100"
fmt.Println(5 / 9 * (f - 32))       // 输出 "0"
fmt.Println(5.0 / 9.0 * (f - 32))   // 输出 "100"
  • 第一行:(f - 32) 是 float64,乘以 5 后依然是 float64,然后除以 9,所有运算都是浮点运算,所以结果正确(100)。
  • 第二行:5 / 9 两个都是无类型整数(隐式为 int),整数除法结果为 0(因为 5/9 小于 1,用整数运算取整),导致整个表达式结果为 0。
  • 第三行:5.0 和 9.0 是无类型浮点常量,所以 5.0/9.0 得到正确的浮点值,再乘以 (f - 32) 得到 100。

关键点:常量的写法决定了它们在运算中的默认类型,从而影响最终结果。这也说明了在使用无类型常量时,要注意数值字面量的形式(整数形式或浮点形式)对运算结果的影响。

fmt.Println(YiB / ZiB) // 输出 "1024"
  • 即便 ZiB 和 YiB 的值超出了 Go 内置整数类型能表达的范围,它们仍然可以参与运算.

类型与接口转换

当无类型常量赋值给接口变量时,接口的动态类型取决于常量的默认类型

fmt.Printf("%T\n", 0)      // 输出 "int"
fmt.Printf("%T\n", 0.0)    // 输出 "float64"
fmt.Printf("%T\n", 0i)     // 输出 "complex128"
fmt.Printf("%T\n", '\000') // 输出 "int32"(也称为 rune)

这对接口编程非常关键,因为接口在运行时需要知道底层数据的具体类型。

语言特性

练习

  1. 编写KB、MB的常量声明,然后扩展到YB。

    const (
        KB = 1000
        MB = 1000 * KB
        GB = 1000 * MB
        TB = 1000 * GB
        PB = 1000 * TB
        EB = 1000 * PB
        ZB = 1000 * EB
        YB = 1000 * ZB
    )
    
    

总结

  1. iota 常量生成器:iota 是一个强大的工具,可以方便地生成有规律的数值序列,适用于枚举、位标志、以及其他有序数值集合的定义。
  2. 有一类常量称为“无类型常量”,这类常量在声明时不被赋予一个具体的基础类型,而是保持一种更“通用”的状态。这样做有两个好处:
    • 更高精度的运算:无类型常量在算术运算中拥有比具体类型(如 int 或 float64)更高的精度(可以看作有 256 位或更多位的精度)。
    • 灵活的隐式转换:当无类型常量赋值给变量时,编译器会自动将它们转换成变量所需要的类型(如果转换合法),这样可以直接用于多种场合,减少显式转换的麻烦。
Go 语言圣经 8.6 并发的web爬虫 8.6 并发的web爬虫 知识点 1.用bfs(广度优先)算法来抓取整个网站 2.每一个彼此独立的抓取命令可以并行进行IO,最大化利用网络资源 代码 func test_web_crawler() { //初步11111 //crawl_one() //优化并发数量22222 //第二个问题是这个程序永远都不会终止,即使它已经爬到了所有... 阅读详情

相关推荐

【血汗泪心路历程】怎么彻底删掉Sangfor文件?怎么彻底删除easyconnect?删除sangfor后网络坏了、某些app无法正常启动怎么解决?

教程来源于网络的五湖四海+gpt解答。用到了好几个教程和方法,遂这篇总结一下。会标明出处!先上一下战绩:终于把sangfor扔进回收站里了!!!哈哈哈那一刻真的好爽。

weixin_71246590的博客 6万+

Go语言圣经

第一章入门

kwdecsdn的博客 2754

第七章-分布式搜索引擎-ES:全文查询、分词查询、精确查询、地理坐标查询、组合查询(bool、funtion_score)以及RestApi

111

weixin_36580930的博客 1630

Go语言圣经总结

如果没有足够的增长空间的话,appendInt函数则会先分配一个足够大(2*len(old_slice),这个扩容算法因不同语言不同)的slice用于保存新的结果,先将输入的x复制到新的空间,然后添加y元素。当调用一个函数的时候,函数的每个调用参数将会被赋值给函数内部的参数变量,所以函数参数变量接收的是一个复制的副本,并不是原始调用的变量。因为函数参数传递的机制导致传递大的数组类型将是低效的,并且对数组参数的任何的修改都是发生在复制的数组上,并不能直接修改调用时原始的数组变量。

yelvens的博客 2058

ADRV9009学习资料保存:基于XC7Z100+ADRV9009的双收双发无线电射频板卡

ADRV9009学习资料保存:基于XC7Z100+ADRV9009的双收双发无线电射频板卡 一、板卡概述 基于XC7Z100+ADRV9009的双收双发无线电射频板卡是基于XilinxZYNQFPGA和ADI的无线收发芯片ADRV9009开发的专用功能板卡,用于5G小基站,无线图传,数据收发...

9353

IBM X3650 M4做raid阵列

步骤1.开机出现此界面,同时按ctrl键和h键,进入IBM X3650 M4配置raid界面。 【注】不知道是不是因为我的服务器长期闲置,按键ctrl键和h键居然无法进入raid配置界面。这时候,我们可以进bios同样可以进入raid配置界面。如果你按ctrl键和h键就可以直接进入raid配置界面,那么请忽略此段,直接看步骤2 开机,按键F1,选中system setting ,接着选中Adapters and UEFI Drivers ...

ani5565的博客 2万+

Go语言圣经(中文版)

http://golang-china.github.io/gopl-zh/index.html

dazheng 1万+

从入门到精通!Arduino 全栈开发深度指南

本文围绕 Arduino 开发撰写全攻略,从基础入门到高级应用层层递进。开篇介绍 Arduino 概念、优势及硬件家族,引导读者完成开发环境搭建与首个 LED 闪烁项目;深入讲解编程语法、I/O 控制及通信协议;详细阐述传感器、模块应用与调试优化技巧;最后以自定义库开发、低功耗设计等高级内容收尾,并给出综合项目案例与产品化思路。无论新手入门,还是开发者进阶,均可从中系统学习 Arduino 知识,掌握从理论到实践的全流程开发技能。

邓邓子的博客 2754

GO语言从入门到达人--GO语言圣经--入门

1.Go的一些基本规范 GO是编译型语言。Go的工具链讲程序的源文件转变为机器相关的原生二进制 GO原生地支持Unicode,支持任何国家的语言。 GO语言其实由三部分组成 : 1.声明自己属于哪个包 package main 2.导入其他包 import (“fmt”) 3.程序本身 func main(){ 代码块 } 一般import后面是组成函数 – func 函数 const 常量 var 变量 type 类型 GO语言不适用分号进行结尾。 GO语言的" { "是不可以单独一行的,必须与f

weixin_44324366的博客 670

Python爬虫实战:携程旅游攻略爬取全流程解析(动态接口+反爬破解+异步爬取)

本文介绍了携程旅游攻略的爬取全流程,涵盖静态和动态页面抓取、异步请求、高级反爬策略以及数据存储和简单分析。增加用户评论和评分抓取结合NLP分析攻略文本情感与关键词建立旅游推荐系统自动化代理IP池和验证码识别模块。

2201_76125261的博客 2039

人工智能_大模型095_Web版003_deepseek R1本地安装_私有化部署_支持RAG_调用HTTPAPI做自己的AI应用_安装RagFlow以及使用_---人工智能工作笔记0240

这里的一定要注意,是资源不够用了,可以点击ragflow-server左边的小绿点,查看 结果。注意去把内存改成10G把至少,我这里改成了10G,因为电脑一共就16G,再试试吧.可以看日志,就显示的是没有连接上mysql,结果我一看,mysql,根本没启动.然后下面选择general就可以了,然后点击确定,然后再去点击。手动去启动,然后再去试试,注意,内存这里给8G太小了还是.调成8G了,然后硬盘大了大了一些换成50G了,然后。点击系统模型设置可以看到,选择聊天模型就可以了,

添柴程序猿的专栏 446

Go语言圣经 - 第6章 方法 - 6.3 通过嵌入结构体来扩展类型

第6章 方法 从90年代开始,面向对象编程(OOP)就成了称霸工程界和教育界的编程范式,所以之后几乎所有大规模被应用的语言都包含了对OOP的支持,Go语言也不例外 关于OOP,其实没有明确定义,但是大概的意思是,一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些方法,而一个方法则是一个一个和特殊类型相关联的函数,一个面向对象的程序会用方法来表达其属性和对应的操作,这样使用这个对象的用户就不需要直接去操作对象,而是借助方法来做这些事情 在早些章节,其实我们已经使用过标准库提供的一些方法,比如t

weixin_51487151的博客 910

【AUTOSAR SystemServices】AUTOSAR CP中Watchdog Manager模块技术解析

本文深入解析了AUTOSAR中的Watchdog Manager模块实现。该模块通过多层次监督机制(Alive/Deadline/Logical Supervision)确保系统安全运行,具备动态模式切换和分级故障处理能力。 关键实现包括: 数据结构设计:包含监督实体状态结构体(实时状态维护)、监督配置结构体(支持模式切换)和全局状态信息(系统级监控) 核心流程优化:初始化采用事务性设计,检查点处理通过条件编译优化,主监控循环采用流水线式并行处理 监督机制实现:Alive监督采用滑动窗口算法,Deadlin

1038

【Go语言圣经2.3】

函数中返回局部变量地址:在 Go 中,返回函数中局部变量的地址是安全的,因为编译器会根据逃逸分析决定将该变量分配在堆上。每个变量在内存中都有一个地址。变量的生命周期决定了它们在内存中存在的时间长短,而作用域决定了变量在代码中可以被访问的范围。对同一变量取地址或复制指针,都为该变量创建了新的别名,通过 *p 访问到的就是同一个变量的值。会创建一个 T 类型的匿名变量,将其初始化为 T 的零值,并返回其地址(类型为 *T)。如果同一词法域中已有部分变量存在,那么“:=”会对已有变量进行赋值,同时声明新的变量。

Pyroyster的博客 2044

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

《GO语言圣经》学习初感与建议

前言 今天刚看了《GO语言圣经》的前二十页,感触颇深,深感此书之精髓,令人叹服,决定从今日起,记录下啃书的收获与感悟,与君共勉!!! 在记录中,我会有选择的进行分享,对那些自我感觉比较关键的细细解读,一些不是太重要的我就简单略过了,以此节省大家的时间。有兴趣的小伙伴可以边看书边看我的博客,有什么想法跟我交流交流,一起进步一起成长,效果想必是极好的。 学习建议 首先说一下,我自学GO...

weixin_42940826的博客 6936

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

go语言圣经读书笔记(上)

总而言之,go总结了很多厉害语言经验,由大佬们组队创造的,如图。

weixin_56551472的博客 1971

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【go语言圣经1.3】

标准化输出 format格式化动词%d 十进制整数%x, %o, %b 十六进制,八进制,二进制整数。%f, %g, %e 浮点数: 3.141593 3.141592653589793 3.141593e+00%t 布尔:true或false%c 字符(rune) (Unicode码点)%s 字符串%q 带双引号的字符串"abc"或带单引号的字符'c'%v 变量的自然形式(natural format)%T 变量的类型%% 字面上的百分号标志(无操作数)转义字符。

Pyroyster的博客 882

【Go语言圣经3.1】

你有一个数字钟表,比如钟表上标有数字0到11。当你往前走时,比如从10走2步,就会变成0。两的补码就利用了这种“绕圈”的特性,把数字“绕回来”来表示负数。“两的补码”这个名字来源于它表示负数的方法:在二进制中,用一种方法把一个正数变成它的负数,而这个方法实际上就是用“2的幂”来做补数。因为2^n的基础是2,所以这种方法叫做两的补码。假设我们用8位二进制来表示数字,负数的表示其实就是“2^8减去正数”。比如-5此时是256-5。

Pyroyster的博客 794

《go 语言圣经》笔记

最近看了《go 语言圣经》这本书,发现 go 语言很有趣,对于语法就不必关注,主要记录了一些语言特性(相对于其他语言而言)的笔记。 Go(又称Golang)是 Google 开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。 package Go 语言的代码通过包(package)组织,包类似于其它语言里的库(libraries)或者模块 (modules)。 Go语言中的包和其他语言的库或模块的概念类似,目的都是为了支持模块化、封装、单独编译和代码重用。每个包都对应一个独立的名字

fcsfcsfcs的博客 795

Go学习圣经:0基础精通GO开发与高并发架构(1)

从Java高薪岗位和就业岗位来看,云原生、K8S、GO 现在对于 高级工程师/架构师来说,越来越重要。尼恩从架构师视角出发,基于自己的尼恩 3高架构师知识体系和知识宇宙,写一本《GO学习圣经》。

架构师尼恩 4753

go语言圣经读书笔记(下)

进程线程协程区别,程序是写的代码生成的二进制文件,是一个静态的概念,写好了就放在那了,而进程是一个动态的概念,同一个进程享有同一份资源,进程是程序运行时的描述,可以分为5种状态。创建态,就绪态,执行态,阻塞态,终止态,就是程序开始后就交给操作系统来管理以进程的方式。,在程序执行中有时要面临多个任务,老式程序中只能顺序执行,视频时不能发消息,现在程序可以利用线程来解决这种问题,一个进程中可以含有多个线程,线程之间可以并发,从而达到边发消息边视频的功能。

weixin_56551472的博客 1637

go语言圣经中文版pdf_我的 Go 语言学习之路

原创: Go中文网 Go语言中文网 个人情况简介徐新华(polaris),Go 中文网站长。目前在北京一家创业公司担任 CTO。2011 年春,北京大学硕士毕业,先后在开心网、奇虎 360 工作。本人一直从事服务端相关工作,有着丰富的经验,对前端也有所掌握,Android 开发也了解些。虽然目前管理方面的事情较多,但一直保持着技术学习。擅长服务端技术和架构。我与 Go 语言2012 年 3 月,G...

weixin_39890629的博客 1415

《Go语言圣经》第一章 - 读书笔记

《Go语言圣经》第一章 命令行参数 练习1.1 练习1.2 练习1.3 查找重复的行 练习1.4 GIF 动画 练习1.5 练习1.6 获取URL 练习1.7 练习1.8 练习1.9 并发获取多个URL 练习1.10 练习1.11 Web服务 练习1.12 本章要点 控制流 命名类型 指针 方法和接口 包(packages)注释

Pola_的博客 2239

golang类型断言理解[go语言圣经]

Go 语言中的类型断言是什么?理解关键点是: 首先,x.(T), x必然是一个接口,接口有3个属性具体类型的属性 1. 接口动态类型 2. 接口的动态值 3. 接口的方法集合 T取值:x取值:如果为nil,会panic, 类型断言是一个使用在接口值上的操作。语法上它看起来像x.(T)被称为断言类型,这里x表示一个接口的类型和T表示一个类型。一个类型断言检查它操作对象的动态类...

单林敏的博客 592

Go学习圣经:Go语言实现高并发CRUD业务开发

从Java高薪岗位和就业岗位来看,云原生、K8S、GO 现在对于 高级工程师/架构师 来说,越来越重要。尼恩从架构师视角出发,基于尼恩3高架构知识宇宙,写一本《GO学习圣经》。

架构师尼恩 3278

Go语言圣经笔记

Go圣经 i++是语句,而不是表达式,所以类似j=i++非法,并且++只能在后边 常量目前只能是数值、字符串或者一个固定的布尔值 变量 基本类型:数值、字符串、布尔值 引用类型:指针、接口、切片、map、函数、chan 聚合类型:数组、结构体 Go中声明变量不初始化的情况下都会默认零值,不会出现undefined的情况 引用类型的零值为nil 基本类型为其对应的零值 聚合类型的元素或字段为其对应的零值 短变量声明对已经声明过的变量只有赋值作用,但是多次变量声明必须要有一个是新的变量 res,er

how2js的博客 260
上一篇: 【Go语言圣经3.1】
下一篇: 【Go语言圣经5.1】
Pyroyster
博客等级 码龄7年 206粉丝 55原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值