【go语言圣经1.3】

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

概念

  1. map 数据类型
    • map 存储了键/值(key/value)的集合,对集合元素,提供常数时间的存、取或测试操作。键可以是任意类型,只要其值能用 == 运算符比较,最常见的例子是字符串;值则可以是任意类型。这个例子中的键是字符串,值是整数。内置函数 make 创建空 map,此外,它还有别的作用。4.3 节讨论 map。
    • 从功能和实现上说,Go 的 map 类似于 Java 语言中的 HashMap,Python 语言中的 dict,Lua 语言中的 table,通常使用 hash 实现

语言特性

  1. if 语句:条件部分不需要括号,但主体必须用大括号包围。

  2. Go 中只有 for 一种循环形式,可以写成传统 for 循环、while 循环形式或无限循环。

  3. 通过 range 遍历 map 或切片时,返回的顺序是不确定的,这要求程序不能依赖遍历顺序。

  4. 标准输入与文件输入都通过类似方式处理:使用 bufio.Scanner 或 ioutil.ReadFile。不同之处在于:前者逐行读取适合大数据流,后者适合一次性加载整个文件

  5. map 是一种引用类型(这里的“引用”类似于指针,但语法上更加简单)

    • 当你使用 make(map[string]int) 创建一个 map 时,实际上 Go 分配了一块内存来存储这个 map 的数据,并返回了一个引用,这个引用指向那块内存。你可以把这个引用看作是一个“地址”,它告诉程序实际数据存储在哪里。
    • 当你将 map 作为参数传递给函数时,传递的是这个引用的一个副本(浅拷贝),而不是整个 map 数据结构的拷贝。副本只是另一个指向同一块内存的引用。
    • 因为传入函数的 map 引用(副本)和原始的 map 引用都指向同一块内存,所以在函数内部对 map 的修改(如增加、删除或更新键值对)会直接影响到这块内存。结果就是,无论是在函数内部还是外部,你看到的都是同一份数据。
    • 再次强调:对于 map,使用赋值语句或者传递参数时,实际上只是把这个 map 的引用复制了一份(浅拷贝)。新变量和原变量都指向同一块内存区域。
    original := map[string]int{"age": 20}
    copyRef := original // 复制的是引用,而非数据内容的独立副本
    
    copyMap := deepCopy(original) // 相当于手动复制了 map 的每个键值对
    
    

要点(案例)

通过 dup 程序的三个版本,我们可以看到 Go 语言在文本处理上的多种方法和技巧:

  • dup1 采用流式读取和 map 统计的方式,适合处理标准输入;
  • dup2 在此基础上扩展到处理具名文件,并引入了错误处理;
  • dup3 则展示了如何一次性读取整个文件,再用字符串分割方法处理数据。

在 dup 程序中,核心思想是扫描输入中的每一行,然后利用数据结构统计每一行出现的次数,最后只输出出现多次的行。

这个思路在许多文本处理工具中都非常常见,比如 Unix 中的 uniq 命令(寻找相邻的重复行)

// Dup1 prints the text of each line that appears more than
// once in the standard input, preceded by its count.
package main

import (
    "bufio"
    "fmt"
    "os"
)

int main() {
	counts := make(map[string]int)
	input := bufio.NewScanner(os.Stdin)
	for input.Scan() {
		counts[input.Text()]++
	}
}

// NOTE: ignoring potential errors from input.Err()
for line, n := range counts{
	if n > 1 {
		fmt.Printf("%d\t%s\n", n, line)
	}
}

  • bufio:提供高效的缓冲输入,主要用于按行读取文本。
  • os:提供与操作系统交互的能力,比如读取标准输入
  • 主要数据结构——map
    • 使用 make(map[string]int) 创建了一个空的 map,该 map 的键为字符串(每一行的内容),值为整型(该行出现的次数)。
    • 当某一行首次出现时,由于 map 默认值为该类型的零值(对 int 来说为 0),直接进行自增操作 counts[input.Text()]++ 即可。
  • bufio.Scanner
    • Scanner 类型是 bufio 包最有用的特性之一,它读取输入并将其拆成行或单词;通常是处理行形式的输入最简单的方法
    • bufio.NewScanner(os.Stdin) 创建了一个扫描器,用于逐行读取标准输入。
    • 调用 input.Scan() 读取下一行, 并移除行末的换行符(当没有更多输入时返回 false)
    • 调用 input.Text() 可以获取当前扫描到的行(已经去掉了换行符)
// Dup2 prints the count and text of lines that appear more than once
// in the input.  It reads from stdin or from a list of named files.
package main

import (
    "bufio"
    "fmt"
    "os"
)

func main(){
	counts := make(map[string]int)
	
	files := os.Args[1:]
	if len(files) == 0 {
		countLines(os.Stdin, counts)
	} else {
		for _, arg := range files{
			f, err := os.Open(arg)
			if err != nil {
				fmt.Fprintf(os.Stderr, "dup2:%v\n", err)
				continue
			}
			countLines(f, counts)
			f.Close()
		}
	}

	for line, n := range counts {
        if n > 1 {
            fmt.Printf("%d\t%s\n", n, line)
        }
    }
}

func countLines(f *os.File, counts map[string]int){
	input := bufio.NewScanner(f)
	for input.Scan() {
		counts[input.Text()]++
	}
	// NOTE: ignoring potential errors from input.Err()
}
  • 扩展读取具名函数的能力
  • 将按行读取并计数的逻辑提取到独立的函数 countLines 中
    • 由于 map 是引用类型,将其作为参数传递后,函数内部对 map 的修改会反映到外部。
// 使用一种不同的方法:一次性将整个文件内容读入内存,再进行分割处理

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "strings"
)

func main() {
	counts := make(map[string]int)
    for _, filename := range os.Args[1:] {
        data, err := ioutil.ReadFile(filename)
        if err != nil {
            fmt.Fprintf(os.Stderr, "dup3: %v\n", err)
            continue
        }
        for _, line := range strings.Split(string(data), "\n") {
            counts[line]++
        }
    }
    for line, n := range counts {
        if n > 1 {
            fmt.Printf("%d\t%s\n", n, line)
        }
    }
}

  • ioutil.ReadFile 函数用于一次性读取整个文件内容,返回的是字节切片。
  • 需要将字节切片转换为字符串后 string(data),才能使用 strings.Split 按换行符分割成多个行。
  • 适用场景
    • 当输入数据较小或对内存要求不高时,一次性读取所有内容简化了处理过程;
    • 对于大文件或内存敏感的应用,前两种基于流式处理的方式(dup1 和 dup2)更合适。

总结与补充

  1. 标准化输出 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          变量的类型
      %%          字面上的百分号标志(无操作数)
      
      
    • 转义字符

  2. strings包的常用函数
    • strings.Split(s, sep string) []string 将字符串s按照分隔符sep分割成子串,并返回字符串切片
    • strings.Join(a []string, sep string) string将字符串切片a中的各个元素以分隔符sep连接成一个单一的字符串
深入解析Vortex GPGPU cache设计(2),关于cache_bank 本文分析了Vortex处理器的cache_bank模块设计,作为cache系列的第二部分。文章详细阐述了cache_bank的基本结构,包括地址位分配和默认配置参数。重点解析了cache的5种操作及其优先级。文章详细介绍了二级流水线设计,包括TAG/DATARAM的读写操作时序。 阅读详情

相关推荐

别再自己写组件了!用uni-app的midButton属性5分钟搞定中间凸起TabBar(H5/小程序通用)

本文详细介绍了uni-app官方提供的midButton属性,帮助开发者5分钟内实现中间凸起的TabBar效果,无需编写繁琐的自定义组件代码。该方案兼容H5和微信小程序平台,配置简单且维护成本低,大幅提升开发效率和性能表现。

weixin_30431445的博客 347

Go语言圣经

第一章入门

kwdecsdn的博客 2754

深空探测处理软件USGS-ISIS的下载安装

深空探测处理软件USGS-ISIS下载安装教程

qq_31721595的博客 3310

Go语言圣经总结

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

yelvens的博客 2058

AI提示词实战:用EARS语法5步搞定产品需求拆解(附完整案例)

本文详细介绍了如何运用EARS语法将模糊的产品需求进行原子化拆解,转化为清晰、可执行的结构化指令。通过一个完整的自由职业者项目管理工具案例,演示了从原始需求分析到构建增强AI提示词的五步实战流程,帮助产品经理和技术人员实现高效、精准的需求传达与协作。

nokia的博客 1030

DreamerV3实战:如何用世界模型在Minecraft中自动挖钻石(附完整训练流程)

本文详细介绍了如何使用DreamerV3世界模型在Minecraft中训练AI智能体自动完成挖钻石的复杂任务。文章深入分析了该任务对强化学习的挑战,提供了从环境配置、模型训练到结果评估的完整实战流程,并分享了关键的调优技巧与问题解决方案,展示了基于模型的强化学习在解决稀疏奖励问题上的强大能力。

weixin_29050271的博客 189

Go语言圣经(中文版)

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

dazheng 1万+

国产麒麟系统PXE安装-UEFI引导

注意: 适用uefi引导 适用x86_64架构 一键部署脚本扣我 1.上传ISO到PXE服务器,拷贝ISO文件 # mkdir /kylin_iso # mount -o loop Kylin-Server-10-SP1-Release-Build04-20200711-x86_64.iso /kylin_iso/ 2.配置http,获取安装源 # yum -y install httpd # mkdir /var/www/html/{ks,kylin} # 注意一定是"/kylin_iso/

河静 5053

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

cs231n作业 assignment 1 q1 q2 q3

请先看课程作业地址。有两种做作业的方法,一种是在google Colab上做 (需魔法),另一种就是下载到本地,但是我懒得在本地配置环境,太麻烦了,还得修改一些基础代码,我就直接在google colab上做了google colab 配置环境只需要跟着教程走就好了最后还有一题解答题懒得做的,这个题目做的没啥意思。让我们用简单写法来实现softmax的loss函数与梯度计算。

Leezed525的博客 9277

Autosar CAN 网络管理标准文档

Autosar CAN 网络管理标准文档

蚂蚁小兵 923

【Go语言圣经3.1】

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

Pyroyster的博客 794

MimicKit 人形机器人强化学习全身模仿控制算法使用教程

本文介绍了MimicKit运动模仿算法框架的使用指南。主要内容包括:1)安装IsaacGym和依赖项;2)训练模型命令及参数说明;3)测试模型的方法;4)分布式训练配置;5)使用TensorBoard可视化日志;6)动作数据格式说明。该框架支持DeepMimic、AMP、ASE、ADD等算法,包含PPO、AWR等强化学习算法,适用于物理仿真角色动画控制研究。

机器人控制与仿真应用 1199

【go语言圣经】练习1.1-1.3

描述: 做实验测量潜在低效的版本和使用了 strings.Join 的版本的运行时间差异。描述:修改 echo 程序,使其能够打印 os.Args[0] ,即被执行命令本身的名字。节讲解了部分 time 包,11.4节展示了如何写标准测试程序,以得到系统性的性能评测。PS:运行了几次,大概是方式一消耗的时间多一点,但是直接测试时间并不精确。新建了一个xxx_test.go文件,必须跟xxx.go文件在同一目录。描述:修改 echo 程序,使其打印每个参数的索引和值,每个一行。

yj1248805281的博客 537

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Go语言圣经 - 第1章 入门 - 1.3 & 1.4 查找重复的行 & GIF

第1章 入门 1.3 查找重复的行 在1.2节,我们简单的了解了一些Go语言的基本语法,接下来我们再来看一个例子进一步学习 对文件做拷贝、打印、搜索和排序、统计或类似事情的程序都有一个差不多的程序结构:一个处理输入的循环,再每个元素上执行计算处理,在处理的同时或最后产生输出。我们来通过一些案例深入理解下这种程序结构 case 1: func main() { counts := make(map[string]int) input:= bufio.NewScanner(os.Stdin)

weixin_51487151的博客 314

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

《Go语言圣经练习题》

【代码】《Go语言圣经练习题》

weixin_43495948的博客 524

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【go语言圣经】练习答案--第三章

练习 3.1: 如果f函数返回的是无限制的float64值,那么SVG文件可能输出无效的多边形元素(虽然许多SVG渲染器会妥善处理这类问题)。修改程序跳过无效的多边形。 package main import ( "fmt" "math" ) const ( width, height = 600, 320 //画布大小 cells = 100...

金戋的博客 2677

【Go语言圣经2.3】

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

Pyroyster的博客 2044

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

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

架构师尼恩 4753

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

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

weixin_56551472的博客 1971

《Go语言圣经》笔记(1-4章)

一、入门 1、hello world Go不需要加分号 “{” 符号必须和关键字func在同一行,不能独自成行。并且在 x+y 这个表达式中,换行符可以在+操作符的后面,但是不能在+操作符的前面 为了在一个包下的多个文件能同时编写main方法,可以在无用的文件前面加 //go:build ignore // +build ignore 2、 命令行参数 os包提供一些函数和变量。命令行参数以os包中Args名字的变量供程序访问,在os包外面,使用os.Args这个名字。变量os.Args是一个字符串

shenxinde的博客 5162

【Go语言圣经3.6】

iota 常量生成器:iota 是一个强大的工具,可以方便地生成有规律的数值序列,适用于枚举、位标志、以及其他有序数值集合的定义。有一类常量称为“无类型常量”,这类常量在声明时不被赋予一个具体的基础类型,而是保持一种更“通用”的状态。这样做有两个好处:更高精度的运算:无类型常量在算术运算中拥有比具体类型(如 int 或 float64)更高的精度(可以看作有 256 位或更多位的精度)。灵活的隐式转换。

Pyroyster的博客 1199

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

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

weixin_42940826的博客 6936

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

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

weixin_39890629的博客 1415

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

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

weixin_56551472的博客 1637

《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
上一篇: 【LeetCode222】完全二叉树的节点个数
下一篇: 【LeetCode110】平衡二叉树
Pyroyster
博客等级 码龄7年 206粉丝 55原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值