go中我遇到的问题总结

go问题总结


1 - go中的nil等于java中的null吗

在 Go 和 Java 中,nilnull 都用于表示“空值”,但它们的实现和使用方式有所不同。

以下是 Go 中的 nil 和 Java 中的 null 之间的对比:

1. Go 中的 nil

在 Go 中,nil 是一个预定义的常量,表示零值。它的行为根据数据类型的不同而有所不同:

  • 对于指针、切片、映射、通道、接口和函数类型,nil 表示“没有指向任何地方”。
  • 对于基本数据类型(如 int、float 等),nil 不适用,Go 会使用对应类型的零值(例如 0false"")。
示例:
package mainimport "fmt"func main() {var ptr *intvar arr []intvar ch chan intvar m map[string]intfmt.Println(ptr == nil) // truefmt.Println(arr == nil) // truefmt.Println(ch == nil)  // truefmt.Println(m == nil)   // true
}

2. Java 中的 null

在 Java 中,null 是一个常量,表示没有对象的引用。它可以赋给任何对象类型的变量,但不能赋给基本数据类型(如 intchar 等)。对于基本数据类型,Java 会使用默认值(例如 0false"")。

示例:
public class Main {public static void main(String[] args) {Integer num = null;String str = null;System.out.println(num == null); // trueSystem.out.println(str == null); // true}
}

3. 对比

特性Go 中的 nilJava 中的 null
适用类型指针、切片、映射、通道、接口、函数等任何对象类型(包括类、接口、数组等)
基本数据类型对于基本数据类型有零值(如 0false对于基本数据类型不适用,使用默认值(如 0
空值判断可以直接使用 == nil 判断可以直接使用 == null 判断

4. 总结

  • nilnull 都表示“没有值”,但 Go 中的 nil 更为广泛,适用于多种类型,包括接口、切片等,而 Java 的 null 只能用于对象类型。
  • 在 Go 中,基本数据类型不会使用 nil,而 Java 的基本类型有默认值,不能为 null

2 - go中基本数据类型可以用nil进行判断吗

在 Go 中,基本数据类型(如 intfloat64bool 等)不能使用 nil 进行判断。nil 仅适用于指针、切片、映射、通道、接口、函数等引用类型。对于基本数据类型,Go 会使用相应的零值,而不能将其赋值为 nil


1. 基本数据类型的零值

在 Go 中,基本数据类型有对应的零值,以下是一些常见的零值:

  • int0
  • float640.0
  • boolfalse
  • string""(空字符串)

这些零值与 nil 不同,不能通过 nil 来判断。

2. 示例:基本数据类型不能用 nil 判断

package mainimport "fmt"func main() {var i intvar f float64var b boolvar s stringfmt.Println(i == nil)   // 编译错误fmt.Println(f == nil)   // 编译错误fmt.Println(b == nil)   // 编译错误fmt.Println(s == nil)   // 编译错误
}

3. 解决方法

对于基本数据类型,你可以通过比较它们是否等于零值来进行判断,例如:

package mainimport "fmt"func main() {var i intvar f float64var b boolvar s stringfmt.Println(i == 0)    // truefmt.Println(f == 0.0)  // truefmt.Println(b == false) // truefmt.Println(s == "")   // true
}

4. 总结

  • 基本数据类型不能用 nil 判断,它们有自己的零值。
  • 对于基本数据类型,应直接与零值进行比较(如 i == 0s == "")。
  • nil 只能用于引用类型(指针、切片、映射等)。

3-结构体方法和普通方法的区别

在 Go 语言中,结构体方法和普通方法(即函数)是两个常见的概念。虽然它们都定义了代码的行为,但它们的实现和使用方式有所不同。下面是它们的区别:


1. 结构体方法

结构体方法是与结构体类型(struct)关联的函数。它们可以访问和修改结构体的字段。通过给结构体定义方法,可以使结构体类型具备一定的行为。

特点:
  • 结构体方法与某个特定的结构体类型关联。
  • 结构体方法可以访问结构体的字段。
  • 结构体方法的接收者是结构体类型或结构体指针。
示例:
package mainimport "fmt"// 定义一个结构体
type Person struct {Name stringAge  int
}// 结构体方法:修改结构体的字段
func (p *Person) SetAge(age int) {p.Age = age
}// 结构体方法:打印结构体内容
func (p Person) Greet() {fmt.Println("Hello, my name is", p.Name, "and I am", p.Age, "years old.")
}func main() {person := Person{Name: "John", Age: 25}person.Greet()    // 输出: Hello, my name is John and I am 25 years old.person.SetAge(30) // 修改结构体的字段person.Greet()    // 输出: Hello, my name is John and I am 30 years old.
}

2. 普通方法(函数)

普通方法(即函数)是独立于任何类型之外的。它不依赖于结构体或其他类型,但它可以作为参数或返回值与其他类型交互。

特点:
  • 普通方法与任何类型无关。
  • 普通方法不能访问结构体的字段或方法。
  • 普通方法通常用于一般的功能实现,适用于所有类型。
示例:
package mainimport "fmt"// 普通函数:两个数字相加
func Add(a, b int) int {return a + b
}func main() {result := Add(5, 3) // 调用普通函数fmt.Println("Result of Add:", result) // 输出: Result of Add: 8
}

3. 主要区别

特性结构体方法普通方法(函数)
与类型的关系与特定类型(如结构体)关联独立于任何类型,通常是全局函数
接收者有一个接收者,通常是结构体类型或结构体指针(通过接收者访问字段)没有接收者
访问结构体字段可以访问结构体字段,通过接收者修改字段值不能访问结构体的字段
用法用于为结构体添加行为或功能用于实现通用的功能,适用于任何类型

4. 总结

  • 结构体方法:与结构体类型紧密关联,可以访问和修改结构体的字段。通过接收者来定义和实现。
  • 普通方法(函数):不与任何类型关联,不访问结构体字段,适用于通用功能。

4 - 为什么在struct中实现了String方法,fmt.Println(&stu)就会自动调用你实现的方法

注释解析:// 如果你实现了 *Student 类型的 String 方法,就会自动调用

这段注释出现在 Go 语言的代码中,解释了当使用 fmt.Println(&stu) 这种方式打印结构体时,Go 是如何处理打印逻辑的。我们来详细拆解一下:


🧩 背景知识:fmt.Println() 是如何工作的?

在 Go 语言中,fmt 包在打印一个值时会尝试判断该值是否实现了某些接口,最重要的是:

type Stringer interface {String() string
}

如果某个类型实现了这个接口,fmt 就会自动调用 String() 方法来获取要打印的字符串。


🧪 示例说明:

package mainimport "fmt"type Student struct {Name stringAge  int
}// 给 *Student 类型实现 String 方法
func (s *Student) String() string {return fmt.Sprintf("Student(Name: %s, Age: %d)", s.Name, s.Age)
}func main() {stu := Student{Name: "Tom", Age: 20}fmt.Println(&stu) // 自动调用 (*Student).String() 方法
}

✅ 注释解释:

// 如果你实现了 *Student 类型的 String 方法,就会自动调用
fmt.Println(&stu)
🔍 解释如下:
  • *Student 表示 Student 类型的指针

  • 如果你为 *Student 实现了 String() string 方法:

    func (s *Student) String() string { ... }
    
  • 当你使用 fmt.Println(&stu) 时,fmt 会检测 *Student 是否实现了 Stringer 接口。

  • 如果实现了,就会自动调用这个方法,而不是打印默认格式的结构体内容。


❗ 注意事项:

如果你实现的是 Student(非指针)类型的 String() 方法

func (s Student) String() string {// ...
}

那么只有在传值时(fmt.Println(stu))才会自动调用 String() 方法,fmt.Println(&stu) 不会自动调用。


🔚 小结

  • fmt.Println(&stu) 中的 &stu*Student 类型。
  • 如果你为 *Student 实现了 String() 方法,fmt.Println(&stu)自动调用这个方法
  • 这是因为 fmt 包内部会优先调用类型的 String() 方法来打印内容。

5 - (*array)[i][j], (*array)[j][i] = (*array)[j][i], (*array)[i][j]这是什么写法

⛳ Go 中的多重赋值(多值交换)

(*array)[i][j], (*array)[j][i] = (*array)[j][i], (*array)[i][j]

这是 Go 语言中的 多重赋值(multiple assignment)语法,它允许你在一行中交换两个值,不需要临时变量。


🧠 等价写法(更冗长)

temp := (*array)[i][j]
(*array)[i][j] = (*array)[j][i]
(*array)[j][i] = temp

✅ 使用多重赋值的优势

  • ✅ 语法简洁
  • ✅ 不需要 temp 临时变量
  • ✅ 一行搞定,常用于 交换两个变量的值

🧪 示例

a, b := 3, 5
a, b = b, a
fmt.Println(a, b) // 输出:5 3

🚀 在二维数组转置中的应用

二维数组转置时,需要把元素 [i][j][j][i] 的位置互换,原本需要三行代码,现在一行就能搞定。


📌 小结表格

语法说明
a, b = b, a同时交换两个变量的值
x, y, z = 1, 2, 3支持多个变量同时赋值
用途交换变量、并行赋值、多返回值接收

6 - go中的函数和方法不是同一个概念吗

🔍 Go 中的函数(Function)和方法(Method)不是同一个概念!

虽然它们看起来很像,但本质上有区别。下面是详细的 Markdown 格式说明:


🧩 函数(Function)

Go 中最常见的写法就是函数。

func Add(a int, b int) int {return a + b
}
✅ 特点:
  • 没有“接收者”(receiver)
  • 直接调用,比如:Add(1, 2)
  • 通常是通用工具函数,不依赖某个结构体实例

🧱 方法(Method)

方法是绑定到某个**类型(通常是结构体)**的函数。

type Person struct {Name string
}// 方法:带有接收者
func (p Person) SayHello() {fmt.Println("Hello, my name is", p.Name)
}
✅ 特点:
  • 有接收者 p Person,表示这个方法是 Person 类型“专属”的
  • 调用方式:p.SayHello()
  • 方法可以接收值类型(如 Person)或指针类型(如 *Person)作为接收者

🔍 方法 vs 函数 的对比表格

项目函数 Function方法 Method
是否有接收者❌ 无接收者✅ 有接收者((x Type)
调用方式函数名(参数)对象.方法名()
所属属于包(package)属于某个类型(type)
用途通用计算、工具类逻辑操作特定结构体的数据和行为

✨ 示例对比

// 普通函数
func SayHi(name string) {fmt.Println("Hi,", name)
}// 方法
type Cat struct {Name string
}func (c Cat) Meow() {fmt.Println(c.Name, "says Meow~")
}

📌 小结

  • 函数 是“工具”
  • 方法 是“结构体成员行为”
  • 两者写法类似,但用途和归属不一样

7 - 方法和函数底层调用机制(值拷贝 vs 指针传递) 的区别

🔍 方法和函数的底层调用机制(值拷贝 vs 指针传递)详解

/*方法与函数的区别如下:1. 方法(Method)是与某个类型(通常是结构体)绑定的函数。它有一个接收者(receiver),定义格式为:func (接收者名 接收者类型) 方法名(参数...) 返回值 {...}可以通过接收者调用方法,如:instance.MethodName()2. 函数(Function)是独立的,**没有接收者**,调用方式为:FunctionName(参数...),不能通过接收者的方式调用。3. 方法的接收者可以是值类型或指针类型:- 值接收者:会复制调用者,不影响原值。- 指针接收者:传递地址,可修改原值。4. 方法调用时,Go 支持自动取地址或解引用(语法糖)。如:值对象也可以调用指针接收者方法,反之亦然。5. 函数的参数必须严格匹配调用时传入的参数类型,否则会编译报错,不存在自动取地址或解引用。总结:- 方法 = 函数 + 接收者。- 方法更适合面向对象封装,函数更适合工具类的逻辑。
*/

在 Go 语言中,函数调用和方法调用在底层传参机制上,其实是一样的——都是值传递,区别在于你传的是值还是地址


🧩 核心概念

方式本质修改是否影响原始变量常用于
值拷贝传入的是数据的副本❌ 不影响原始变量小结构体、只读操作
指针传递传入的是内存地址✅ 可以影响原始变量修改操作、大结构体

🧪 示例:函数中的值传递 vs 指针传递

type Person struct {Name string
}// 函数:值传递
func ChangeNameByValue(p Person) {p.Name = "张三"
}// 函数:指针传递
func ChangeNameByPointer(p *Person) {p.Name = "李四"
}
func main() {person := Person{Name: "原名"}ChangeNameByValue(person)fmt.Println("值传递结果:", person.Name) // 原名ChangeNameByPointer(&person)fmt.Println("指针传递结果:", person.Name) // 李四
}

🧱 方法的底层本质

在编译期间,Go 会把方法转换成函数调用形式,比如:

func (p Person) Hello() { }

等价于:

func Person_Hello(p Person) { }

如果是指针接收者:

func (p *Person) Hello() { }

等价于:

func Person_Hello(p *Person) { }

🔬 进一步理解值 vs 指针调用

type Data struct {Val int
}func (d Data) ByValue() {d.Val = 100fmt.Println("ByValue 中的值:", d.Val)
}func (d *Data) ByPointer() {d.Val = 200fmt.Println("ByPointer 中的值:", d.Val)
}
func main() {d := Data{Val: 10}d.ByValue()fmt.Println("main中值:", d.Val) // 10d.ByPointer()fmt.Println("main中值:", d.Val) // 200
}

🔧 编译器的语法糖

Go 会帮你做这些自动转换:

  • d.ByPointer() ← 自动加 &,等价于 (&d).ByPointer()
  • (&d).ByValue() ← 自动解引用,等价于 d.ByValue()

只要方法接收者允许,这些转换会自动进行。


✅ 小结

对比点值接收者 / 值传递指针接收者 / 指针传递
是否拷贝结构体✅ 会❌ 不会,传地址
是否修改原对象❌ 否✅ 可以
性能开销📈 拷贝大对象开销高📉 传指针更高效
自动转换支持✅ 自动加/解引用支持✅ 自动加/解引用支持

8 - 各种基本类型转string的常用方法

✅ Go 中各种基本类型转换为 string 的常用方法(Markdown 格式)

在 Go 中,将基本数据类型转换为 string 是开发中的常见需求,以下是常用类型转换方式的总结:


🔢 1. intstring

方法一:使用 strconv.Itoa
import "strconv"i 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/77190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【android telecom 框架分析 01】【基本介绍 2】【BluetoothPhoneService为何没有源码实现】

1. 背景 我们会在很多资料上看到 BluetoothPhoneService 类,但是我们在实际 aosp 中确找不到具体的实现, 这是为何? 这是一个很好的问题!虽然在车载蓝牙电话场景中我们经常提到类似 BluetoothPhoneService 的概念,但…

微机控制电液伺服汽车减震器动态试验系统

微机控制电液伺服汽车减震器动态试验系统,用于对汽车筒式减震器、减震器台架、驾驶室减震装置、发动机悬置软垫总成、发动机前置楔形支撑总成等的示功图试验、速度特性试验。 主要的技术参数: 1、最大试验力:5kN; 2、试验力测量精…

STM32+dht11+rc522+jq8400的简单使用

1.dht11的使用 硬件:3v3,gnd,data数据线接一个gpio,三根线即可 软件: ①dht11.c #include "dht11.h" #include "delay.h" #include "stdbool.h"static STRUCT_DHT11_TYPEDEF dht11;…

AOSP的Doze模式-DeepIdle 初识

前言 从Android 6.0开始,谷歌引入了Doze模式(打盹模式)的省电技术延长电池使用时间。如果用户长时间未使用设备,低电耗模式会延迟应用后台 CPU 和网络活动,从而延长电池续航时间。根据第三方测试显示,两台同样的Nexus 5&#xff…

用Python Pandas高效操作数据库:从查询到写入的完整指南

一、环境准备与数据库连接 1.1 安装依赖库 pip install pandas sqlalchemy psycopg2 # PostgreSQL # 或 pip install pandas sqlalchemy pymysql # MySQL # 或 pip install pandas sqlalchemy # SQLite 1.2 创建数据库引擎 通过SQLAlchemy创建统一接口&#xff1a…

每日一题(小白)暴力娱乐篇31

首先分析一下题意,需要求出2024的因子,因为我们要求与2024互质的数字,为什么呢?因为我们要求互质说直白点就是我和你两个人没有中间人,我们是自然而然认识的,那我们怎么认识呢,就是直接见面对吧…

电控---printf重定向输出

在嵌入式系统开发中,printf 重定向输出是将标准输出(stdout)从默认设备(如主机终端)重新映射到嵌入式设备的特定硬件接口(如串口、LCD、USB等)的过程。 一、核心原理:标准IO库的底层…

快速认识:数据库、数仓(数据仓库)、数据湖与数据运河

数据技术核心概念对比表 概念核心定义核心功能数据特征典型技术/工具核心应用场景数据库结构化数据的「电子档案柜」,按固定 schema 存储和管理数据,支持高效读写和事务处理。实时事务处理(增删改查),确保数据一致性&…

【17】数据结构之图的遍历篇章

目录标题 图的遍历深度优先遍历 Depth First Search广度优先遍历 Breadth First Search 图的遍历 从图中某一个顶点出发,沿着一些边访遍图中所有的顶点,且使用每个顶点仅被访问一次,这个过程称为图的遍历.Graph Traversal. 其中&#xff0c…

简单接口工具(ApiCraft-Web)

ApiCraft-Web 项目介绍 ApiCraft-Web 是一个轻量级的 API 测试工具,提供了简洁直观的界面,帮助开发者快速测试和调试 HTTP 接口。 功能特点 支持多种 HTTP 请求方法(GET、POST、PUT、DELETE)可配置请求参数(Query …

Git进阶操作

Git高阶操作完全指南:解锁专业开发工作流 前言 在当今的软件开发领域,掌握高级Git技能已成为区分普通开发者与专业开发者的关键因素。根据最新的GitHub数据,熟练应用交互式暂存和Rebase等高级功能的开发者,其代码审查通过率平均提…

Python结合AI生成图像艺术作品代码及介绍

为实现生成图像艺术作品,我选用 Stable Diffusion 库结合 Python 编写代码。下面先展示代码,再详细介绍其原理、模块及使用方法等内容。 生成图片代码 import torch from diffusers import StableDiffusionPipeline# 加载预训练模型 pipe StableDiffu…

Linux操作系统--静态库和动态库的生成and四种解决加载找不到动态库的四种方法

目录 必要的知识储备: 生成静态库: 生成动态库: 解决加载找不到动态库的四种方法: 第一种:拷贝到系统默认的库路径 /usr/lib64/ 第二种:在系统默认的库路径/usr/lib64/下建立软链接 第三种&#xff1…

LLM中的N-Gram、TF-IDF和Word embedding

文章目录 1. N-Gram和TF-IDF:通俗易懂的解析1.1 N-Gram:让AI学会"猜词"的技术1.1.1 基本概念1.1.2 工作原理1.1.3 常见类型1.1.4 应用场景1.1.5 优缺点 1.2 TF-IDF:衡量词语重要性的尺子1.2.1 基本概念1.2.2 计算公式1.2.3 为什么需…

Leetcode 3359. 查找最大元素不超过 K 的有序子矩阵【Plus题】

1.题目基本信息 1.1.题目描述 给定一个大小为 m x n 的二维矩阵 grid。同时给定一个 非负整数 k。 返回满足下列条件的 grid 的子矩阵数量: 子矩阵中最大的元素 小于等于 k。 子矩阵的每一行都以 非递增 顺序排序。 矩阵的子矩阵 (x1, y1, x2, y2) 是通过选择…

如何在 Ubuntu 22.04 上安装、配置、使用 Nginx

如何在 Ubuntu 22.04 上安装、配置、使用 Nginx?-阿里云开发者社区 更新应用 sudo apt updatesudo apt upgrade检查必要依赖并安装 sudo apt install -y curl gnupg2 ca-certificates lsb-release安装nginx sudo apt install -y nginx# 启动nginx sudo systemct…

Linux:显示 -bash-4.2$ 问题(CentOS 7)

文章目录 一、原因二、错误示例三、解决办法 一、原因 在 CentOS 7 系统中,如果你看到命令行提示符显示为 -bash-4.2$,一般是 Bash shell 正在运行,并且它没有找到用户的个人配置文件,或者这些文件有问题而未能成功加载。这个提示…

QT6 源(34):随机数生成器类 QRandomGenerator 的源码阅读

&#xff08;1&#xff09;代码来自 qrandom.h &#xff0c;结合官方的注释&#xff1a; #ifndef QRANDOM_H #define QRANDOM_H#include <QtCore/qalgorithms.h> #include <algorithm> // for std::generate #include <random> // for std::mt1993…

第二篇:linux之Xshell使用及相关linux操作

第二篇&#xff1a;linux之Xshell使用及相关linux操作 文章目录 第二篇&#xff1a;linux之Xshell使用及相关linux操作一、Xshell使用1、Xshell安装2、Xshell使用 二、Bash Shell介绍与使用1、什么是Bash Shell(壳)&#xff1f;2、Bash Shell能干什么&#xff1f;3、平时如何使…

MCP(模型上下文协议)学习笔记

学习MCP&#xff08;模型上下文协议&#xff09;的系统化路径&#xff0c;结合技术原理、工具实践和社区资源&#xff0c;帮助你高效掌握这一AI交互标准&#xff1a; 在当今人工智能飞速发展的时代&#xff0c;AI技术正以前所未有的速度改变着我们的生活和工作方式。然而&#…