Go基础一(Maps Functions 可变参数 闭包 递归 Range 指针 字符串和符文 结构体)

Maps

1.创建map make(map[键类型]值类型)
2.设置键值对 name[key]=value;
3. name[key]获取键值
3.1 key不存在 则返回 0
4.len()方法 返回 map 上 键值对数量 len(name)
5.delete()方法 从map中删除 键值对 delete(name,key)
6.clear()方法 map中删除所有键值对 clear(name)
7.map获取值时,可选第二个返回值,第二个值表明map中是否有该键名
第二个返回值 false 表明 没有 该键, true 表示 有该键
用于区分 没有键名 返回的 0 和 有键值对 返回的 0
8.同时声明和初始化map n:=map[键类型]值类型{key1:value1,key2:value2}
9.maps包中有许多使用方法api
9.1 maps.Equal() 判断 两个map是否相同

package mainimport ("fmt""maps"
)func main() {//1.创建map make(map[键类型]值类型)m := make(map[string]int)//2.设置键值对  name[key]=valuem["k1"] = 7m["k2"] = 13fmt.Println("map:", m)//3. name[key]获取键值v1 := m["k1"]fmt.Println("v1:", v1) //7//3.1 key不存在 则返回 0v3 := m["k3"]fmt.Println("v3:", v3)//0//4.len()方法 返回 map 上 键值对数量 len(name)fmt.Println("len:", len(m))//5.delete()方法 从map中删除 键值对 delete(name,key)delete(m, "k2")fmt.Println("map:", m)//6.clear()方法 map中删除所有键值对 clear(name)clear(m)fmt.Println("map:", m)//7.map获取值时,可选第二个返回值,第二个值表明map中是否有该键名//第二个返回值 false 表明 没有 该键, true 表示 有该键//用于区分 没有键名 返回的 0 和 有键值对 返回的 0_, prs := m["k2"]fmt.Println("prs:", prs)//8.同时声明和初始化map     n:=map[键类型]值类型{key1:value1,key2:value2}n := map[string]int{"foo": 1, "bar": 2}fmt.Println("map:", n)//9.maps包中有许多使用方法api//9.1  maps.Equal() 判断 两个map是否相同n2 := map[string]int{"foo": 1, "bar": 2}if maps.Equal(n, n2) {fmt.Println("n == n2")}
}

使用 fmt.Println.打印时,映射以 map[k:v k:v] 格式显示
打印如下

$ go run maps.go 
map: map[k1:7 k2:13]
v1: 7
v3: 0
len: 2
map: map[k1:7]
map: map[]
prs: false
map: map[bar:2 foo:1]
n == n2

Functions

//0.定义函数 func name(args argesType) returnType { return value}
//1.Go 需要显式返回 return, 他不会自动返回最后一个表达式的值
//2.有多个相同类型参数 可以省略前面的类型定义
//3.调用函数 name(args)

package mainimport "fmt"//0.定义函数 func name(args argesType) returnType { return value}
//1.Go 需要显式返回 return, 他不会自动返回最后一个表达式的值
func plus(a int, b int) int {return a + b
}
//2.有多个相同类型参数 可以省略前面的类型定义
func plusPlus(a, b, c int) int {return a + b + c
}//3.调用函数 name(args)
func main() {res := plus(1, 2)fmt.Println("1+2 =", res)res = plusPlus(1, 2, 3)fmt.Println("1+2+3 =", res)
}

打印

	
$ go run functions.go 
1+2 = 3
1+2+3 = 6

Multiple Return Values 多返回值

//1. Go 内置了 多个返回值的支持 reurn 3,7
//2.不同 变量 接收不同返回值
//3.只需要接受 部分返回值,使用空标识符_

package mainimport "fmt"//1. Go 内置了 多个返回值的支持  reurn 3,7
func vals() (int, int) {return 3, 7
}func main() {//2.不同 变量 接收不同返回值a, b := vals()fmt.Println(a)fmt.Println(b)//3.只需要接受 部分返回值,使用空标识符__, c := vals()fmt.Println(c)
}

运行:

$ go run multiple-return-values.go
3
7
7

Variadic Functions 可变参数函数

//0.可变参数 可以使用 任意数量的参数调用,例如fmt.Println
//1.将任意数量int 作为函数参数 nums …int
//1.1 该函数中 nums类型等效于 int[],可以调用 len(),用range迭代
//2.可变参数函数可以 以通常的方式 使用单个参数调用。
//3.如果一个切片slice中已经有多个args 可以这样使用 nums…

在 Go 语言中,nums… 是一种 ​语法糖,用于将切片(slice)展开为可变参数(variadic arguments)。它的作用是“动态解包切片”,而不是“写死”参数。以下是详细解释:

核心概念

  • 可变参数函数
    函数定义时使用 … 表示接受多个参数(数量不固定):

  • ​调用时的 slice…
    当已有数据存储在切片中时,通过 slice… ​动态解包切片元素,作为可变参数传递:

场景写法说明
定义可变参数函数func f(args ...T)...T 表示接受多个 T 类型的参数,函数内 args 类型为 []T(切片)
传递切片给函数f(slice...)必须显式使用 ... 解包切片,否则类型不匹配(需严格区分 []T...T
直接传递多个参数f(1, 2, 3)无需 ...,直接按可变参数传递
package mainimport "fmt"
//0.可变参数 可以使用 任意数量的参数调用,例如fmt.Println//1.将任意数量int 作为函数参数  nums ...int
func sum(nums ...int) {fmt.Print(nums, " ")total := 0//1.1 该函数中 nums类型等效于 int[],可以调用 len(),用range迭代for _, num := range nums {total += num}fmt.Println(total)
}func main() {//2.可变参数函数可以 以通常的方式 使用单个参数调用。sum(1, 2)sum(1, 2, 3)//3.如果一个切片slice中已经有多个args  可以这样使用 nums...nums := []int{1, 2, 3, 4}sum(nums...)
}

运行

$ go run variadic-functions.go 
[1 2] 3
[1 2 3] 6
[1 2 3 4] 10

Closures 闭包

//0.Go 支持匿名函数 ,这些函数可以形成闭包 。当您想要内联定义函数而不必命名它时,匿名函数非常有用。
//1.函数 intSeq 返回另一个函数 为匿名函数 返回的函数在 变量 i 上 形成闭包
//2.调用 intSeq 返回一个函数 给 nextInt
//2.1每次调用nextInt 更新 i
//2.2 如果重新 初始化一个 函数 状态是独立的

package mainimport "fmt"//0.Go 支持匿名函数 ,这些函数可以形成闭包 。当您想要内联定义函数而不必命名它时,匿名函数非常有用。
//1.函数 intSeq 返回另一个函数 为匿名函数  返回的函数在 变量 i 上 形成闭包
func intSeq() func() int {i := 0return func() int {i++return i}
}func main() {//2.调用 intSeq 返回一个函数 给 nextInt nextInt := intSeq()//2.1每次调用nextInt  更新 i fmt.Println(nextInt())fmt.Println(nextInt())fmt.Println(nextInt())//2.2 如果重新 初始化一个 函数  状态是独立的newInts := intSeq()fmt.Println(newInts())
}

执行:

	
$ go run closures.go
1
2
3
1

Recursion 递归

//1. fact函数会自行调用直到达到 fact(0)
//2.匿名函数 也可以是递归的 但是需要在 定义前 显示声明变量
//2.1 fib是在main中 声明的 因此Go知道这里fib调用那个函数

package mainimport "fmt"//1. fact函数会自行调用直到达到 fact(0)
func fact(n int) int {if n == 0 {return 1}return n * fact(n-1)
}func main() {fmt.Println(fact(7))//7的阶乘//2.匿名函数 也可以是递归的 但是需要在 定义前 显示声明变量var fib func(n int) intfib = func(n int) int {if n < 2 {return n}return fib(n-1) + fib(n-2)}//2.1 fib是在main中 声明的 因此Go知道这里fib调用那个函数fmt.Println(fib(7))
}

执行:

$ go run recursion.go 
5040
13

Range over Built-in Types ( Range over 内置类型)

//1.使用 range 对切片中数字求和,不需要索引 使用空标识符 _ 忽略
//2. range 在 切片和数组上 提供 索引 和 值 ,上面不需要索引 使用空标识符 _ 忽略
//3.range 迭代 map 返回 键和值
//3.1range 只迭代 map 键
//4.range 迭代字符串 返回 索引 和 Unicode 码点值

  • 在 Go 语言中,使用 range 遍历字符串时,会逐个迭代字符串中的 ​Unicode 字符(rune)​,并返回两个值:
    ​当前字符的起始字节索引(int 类型)​
    ​当前字符的 Unicode 码点值(rune 类型,即 int32 的别名)​
package mainimport "fmt"func main() {nums := []int{2, 3, 4}sum := 0//1.使用 range 对切片中数字求和,不需要索引 使用空标识符 _ 忽略for _, num := range nums {sum += num}fmt.Println("sum:", sum)//2. range 在 切片和数组上 提供 索引 和 值 ,上面不需要索引 使用空标识符 _ 忽略for i, num := range nums {if num == 3 {fmt.Println("index:", i)}}//3.range 迭代 map  返回 键和值kvs := map[string]string{"a": "apple", "b": "banana"}for k, v := range kvs {fmt.Printf("%s -> %s\n", k, v)}//3.1range 只迭代 map   键 for k := range kvs {fmt.Println("key:", k)}//4.range 迭代字符串 返回 索引 和 Unicode 码点值for i, c := range "go" {fmt.Println(i, c)}
}

执行:

	
$ go run range-over-built-in-types.go
sum: 9
index: 1
a -> apple
b -> banana
key: a
key: b
0 103
1 111

Pointers 指针

//1.参数不使用指针 zeroval 获得的参数 是与传入参数 不同的副本
//2.参数使用指针 zeroptr 获得的参数 和 传入参数 是同一内存地址 修改值 会同时修改
//3.&i 语法 取出i的内存地址,即指向i的指针

package mainimport "fmt"//1.参数不使用指针  zeroval 获得的参数 是与传入参数  不同的副本
func zeroval(ival int) {ival = 0
}
//2.参数使用指针 zeroptr 获得的参数 和 传入参数 是同一内存地址  修改值 会同时修改
func zeroptr(iptr *int) {*iptr = 0
}func main() {i := 1fmt.Println("initial:", i)zeroval(i)fmt.Println("zeroval:", i)//3.&i 语法 取出i的内存地址,即指向i的指针zeroptr(&i)fmt.Println("zeroptr:", i)fmt.Println("pointer:", &i)
}

执行:

$ go run pointers.go
initial: 1
//4.zeroval 不会更改 main 中的 i,但 zeroptr 会,是因为它引用了该变量的内存地址。
zeroval: 1
zeroptr: 0
pointer: 0x42131100

Strings and Runes 字符串和符文

**//1.字符串 等同于 []byte len()返回 bytes 长度
//2.字符串 索引 对应的 值 是原始字节值 构成字节的16进制值
//3.计算字符串中 有多少符文 utf8.RuneCountInString(s) 按顺序解码UTF-8 rune
// range 循环 字符串 解码每个 符文
//4. utf8.DecodeRuneInString(s) 获取 符文 和 对应符文的 字节长度
**

  • Go 字符串是只读的字节切片。该语言和标准库专门将字符串视为以 UTF-8 编码的文本容器。在其他语言中,字符串由 “字符” 组成。在 Go 中,字符的概念称为符文 - 它是 表示 Unicode 码位的整数

  • 在 Go 语言中,utf8.DecodeRuneInString(s) 方法用于 ​解码字符串 s 中的第一个 UTF-8 字符,返回该字符的 Unicode 码点(rune)及其占用的字节数。该方法属于 unicode/utf8 包,专门处理 UTF-8 编码的字符串,适合需要逐字符解析的场景。

package mainimport ("fmt""unicode/utf8"
)func main() {//s 是一个字符串  泰语 表示 helloconst s = "สวัสดี"//1.字符串 等同于 []byte   len()返回 bytes 长度fmt.Println("Len:", len(s))//2.字符串 索引 对应的 值 是原始字节值  构成字节的16进制值for i := 0; i < len(s); i++ {fmt.Printf("%x ", s[i])}fmt.Println()//3.计算字符串中 有多少符文  utf8.RuneCountInString(s)  按顺序解码UTF-8 runefmt.Println("Rune count:", utf8.RuneCountInString(s))// range 循环 字符串 解码每个 符文for idx, runeValue := range s {fmt.Printf("%#U starts at %d\n", runeValue, idx)}//4.  utf8.DecodeRuneInString(s)  获取 符文 和 对应符文的 字节长度fmt.Println("\nUsing DecodeRuneInString")for i, w := 0, 0; i < len(s); i += w {runeValue, width := utf8.DecodeRuneInString(s[i:])fmt.Printf("%#U starts at %d\n", runeValue, i)w = widthexamineRune(runeValue)}
}func examineRune(r rune) {//单引号if r == 't' {fmt.Println("found tee")} else if r == 'ส' {fmt.Println("found so sua")}
}

执行:

	
$ go run strings-and-runes.go
Len: 18
e0 b8 aa e0 b8 a7 e0 b8 b1 e0 b8 aa e0 b8 94 e0 b8 b5 
Rune count: 6
U+0E2A 'ส' starts at 0
U+0E27 'ว' starts at 3
U+0E31 'ั' starts at 6
U+0E2A 'ส' starts at 9
U+0E14 'ด' starts at 12
U+0E35 'ี' starts at 15
Using DecodeRuneInString
U+0E2A 'ส' starts at 0
found so sua
U+0E27 'ว' starts at 3
U+0E31 'ั' starts at 6
U+0E2A 'ส' starts at 9
found so sua
U+0E14 'ด' starts at 12
U+0E35 'ี' starts at 15

Structs 结构体

1. 结构体定义
type person struct {name stringage  int
}

要点:使用 type 结构体名 struct 定义,字段通过 字段名 类型 声明。
代码对应:定义 person 结构体,包含 name(字符串)和 age(整型)字段。


2. 结构体初始化
// 方式1:顺序初始化(需全部字段)
fmt.Println(person{"Bob", 20})// 方式2:命名字段初始化(可省略部分字段)
fmt.Println(person{name: "Alice", age: 30})
fmt.Println(person{name: "Fred"}) // age 默认为 0

要点
• 支持顺序初始化或显式命名字段初始化。
• 未赋值的字段默认为零值(如 int0)。
代码对应:展示三种初始化方式,包括部分字段省略。


3. 结构体指针
// 直接返回结构体指针
fmt.Println(&person{name: "Ann", age: 40})// 通过函数返回指针
func newPerson(name string) *person {p := person{name: name}p.age = 42return &p
}
fmt.Println(newPerson("Jon"))

要点
• 使用 & 直接获取结构体指针。
• 函数返回局部结构体的指针是安全的(Go 自动分配在堆上)。
代码对应newPerson 函数返回指针,演示直接取址。


4. 访问结构体字段
s := person{name: "Sean", age: 50}
fmt.Println(s.name) // 直接访问sp := &s
fmt.Println(sp.age) // 指针自动解引用
sp.age = 51         // 修改字段值
fmt.Println(sp.age)

要点
• 通过 . 访问字段,指针类型会自动解引用。
• 修改指针指向的结构体会影响原变量。
代码对应s.namesp.age 的访问与修改。


5. 匿名结构体
dog := struct {name   stringisGood bool
}{"Rex",true,
}
fmt.Println(dog)

要点
• 无需预定义类型,直接声明匿名结构体并初始化。
• 适用于一次性使用的场景。
代码对应:定义并打印 dog 匿名结构体。


要点代码示例说明
结构体定义type person struct { ... }定义包含字段的结构体类型。
初始化方式person{"Bob", 20}person{name: "Alice"}支持顺序和命名初始化。
结构体指针&person{...}func newPerson() *person直接取址或函数返回指针。
字段访问/修改s.name, sp.age = 51指针自动解引用,直接修改字段。
匿名结构体dog := struct { ... }{...}临时使用的未命名结构体。

通过代码示例清晰展示了 Go 结构体的核心操作,适用于日常开发参考。

package mainimport "fmt"//1.创建结构体  type 结构体名 struct {字段名 类型 }
type person struct {name stringage  int
}//2.
func newPerson(name string) *person {p := person{name: name}p.age = 42return &p
}func main() {fmt.Println(person{"Bob", 20})fmt.Println(person{name: "Alice", age: 30})fmt.Println(person{name: "Fred"})fmt.Println(&person{name: "Ann", age: 40})fmt.Println(newPerson("Jon"))s := person{name: "Sean", age: 50}fmt.Println(s.name)sp := &sfmt.Println(sp.age)sp.age = 51fmt.Println(sp.age)dog := struct {name   stringisGood bool}{"Rex",true,}fmt.Println(dog)
}```
执行:```go
$ go run structs.go
{Bob 20}
{Alice 30}
{Fred 0}
&{Ann 40}
&{Jon 42}
Sean
50
51
{Rex true}

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

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

相关文章

✅ 2025最新 | YOLO 获取 COCO 指标终极指南 | 从标签转换到 COCOAPI 评估 (训练/验证) 全覆盖【B 站教程详解】

✅ YOLO 轻松获取论文 COCO 指标&#xff1a;AP&#xff08;small&#xff0c;medium&#xff0c;large &#xff09;| 从标签转换到 COCOAPI 评估 (训练/验证) 全覆盖 文章目录 一、摘要二、为什么需要 COCO 指标评估 YOLO 模型&#xff1f;三、核心挑战与解决方案 (视频教程核…

ResNet改进(18):添加 CPCA通道先验卷积注意力机制

1. CPCA 模块 CPCA(Channel Prior Convolutional Attention)是一种结合通道先验信息的卷积注意力机制,旨在通过显式建模通道间关系来增强特征表示能力。 核心思想 CPCA的核心思想是将通道注意力机制与卷积操作相结合,同时引入通道先验知识,通过以下方式优化特征学习: 通…

SpringMVC的简单介绍

SpringMVC的简单介绍 SpringMVC 是一个基于 Java 的 Web 框架&#xff0c;是 Spring Framework 中用于构建 Web 应用的一个核心模块。它采用了 模型-视图-控制器 (MVC) 设计模式&#xff0c;能够帮助开发者更加清晰地分离业务逻辑、用户界面和请求处理&#xff0c;从而提高应用…

MES生产工单管理系统,Java+Vue,含源码与文档,实现生产工单全流程管理,提升制造执行效率与精准度

前言&#xff1a; MES生产工单管理系统是制造业数字化转型的核心工具&#xff0c;通过集成生产、数据、库存等模块&#xff0c;实现全流程数字化管理。以下是对各核心功能的详细解析&#xff1a; 一、生产管理 工单全生命周期管理 创建与派发&#xff1a;根据销售订单或生产计…

Redis常见问题排查与解决方案指南

Redis作为高性能的内存数据库&#xff0c;广泛应用于缓存、队列、实时统计等场景。但在实际使用中&#xff0c;开发者和运维人员常会遇到性能下降、内存溢出、主从同步失败等问题。本文将针对高频问题进行详细分析&#xff0c;并提供对应的解决方案和预防措施&#xff0c;助你快…

目标跟踪Deepsort算法学习2025.4.7

一.DeepSORT概述 1.1 算法定义 DeepSORT(Deep Learning and Sorting)是一种先进的多目标跟踪算法,它结合了深度学习和传统的目标跟踪技术,在复杂环境下实现了高精度和鲁棒性的目标跟踪。该算法的核心思想是通过融合目标的外观特征和运动特征,实现对多个目标的持续跟踪,…

从零开始开发HarmonyOS应用并上架

开发环境搭建&#xff08;1-2天&#xff09; 硬件准备 操作系统&#xff1a;Windows 10 64位 或 macOS 10.13 内存&#xff1a;8GB以上&#xff08;推荐16GB&#xff09; 硬盘&#xff1a;至少10GB可用空间 软件安装 下载 DevEco Studio 3.1&#xff08;官网&#xff1a;…

Linux | 无头 Linux 服务器安装和设置

注&#xff1a;本文为 “Headless Linux” 相关文章合辑。 机翻未校。 How to Install and Set Up Headless Linux Server 如何安装和设置无头 Linux 服务器 Winnie Ondara Last Updated: January 31, 2023 A vast majority of Linux users are familiar with a Linux desk…

AI赋能数据库管理“最后一公里”,融合架构重塑数据库承载成本效能——zCloud 6.7与zData X 3.3正式发布

点击蓝字 关注我们 在数据驱动的新时代&#xff0c;数据库的多元化和智能化已成不可逆的趋势。3月31日&#xff0c;云和恩墨以“奇点时刻数智跃迁”为主题举办线上发布会&#xff0c;云和恩墨创始人兼总经理盖国强、公司数据库和生态产品群总经理熊军共同带来 zCloud 6.7与 zD…

I have something to say about Vue Node.js

关于Vue Node.js&#xff0c;我真的说了很多次了&#xff0c;让我难以理解为啥这么粗糙的东西能流行一起。真疯狂的世界。 vue让感觉就像玩猫德一样的&#xff0c;如此的疯狂&#xff0c;天哪。睡觉了 Node.js v13 window7_nodejsv13-CSDN博客

【橘子大模型】使用streamlit来构建自己的聊天机器人(下)

一、简介 我们之前完成了一个简易的聊天机器人&#xff0c;但是还留下了一些问题没有解决&#xff0c;比如如何开启新的会话。如何切换session_id&#xff0c;如何把对话做成流式的输出。这些我们就会在今天来完成。 二、关于新的会话和session_id from dotenv import load_…

php-cgi参数注入攻击经历浅谈

起因&#xff1a; 阿里云服务器再次警告出现挖矿程序。上一次服务器被攻击后&#xff0c;怕有恶意程序残留&#xff0c;第一时间重装了系统&#xff0c;也没有详查攻击入口。不过事后还是做了一些防范&#xff0c;这台留作公网访问的服务器上并未保留业务数据&#xff0c;只作…

自动驾驶中的实时挑战:如何优化车辆动力学模型

自动驾驶中的实时优化:自行车模型与双轨模型的计算复杂度权衡 在自动驾驶领域,车辆动力学建模是实现精准控制和路径规划的关键。自行车模型和双轨模型作为两种主流的建模方法,在实时性需求下如何平衡计算复杂度与精确度,是工程师们必须面对的挑战。本文将深入探讨这两种模…

Hybrid 架构的概念,以及如何优化Hybrid 通信方案,提升页面加载速度和渲染性能

1. 什么是 Hybrid 架构&#xff1f; Hybrid&#xff08;混合&#xff09;架构是指 结合 Web 技术和 Native&#xff08;原生&#xff09;技术 的移动应用开发模式&#xff0c;通常由以下部分组成&#xff1a; Web 部分&#xff1a;使用 HTML、CSS、JavaScript&#xff08;或前…

关于类模板STL中vector容器的运用和智能指针的实现

代码题&#xff1a;使用vector实现一个简单的本地注册登录系统 注册&#xff1a;将账号密码存入vector里面&#xff0c;注意防重复判断 登录&#xff1a;判断登录的账号密码是否正确 #include <iostream> #include <cstring> #include <cstdlib> #in…

OpenCV 从入门到精通(day_04)

1. 绘制图像轮廓 1.1 什么是轮廓 轮廓是一系列相连的点组成的曲线&#xff0c;代表了物体的基本外形。相对于边缘&#xff0c;轮廓是连续的&#xff0c;边缘不一定连续&#xff0c;如下图所示。其实边缘主要是作为图像的特征使用&#xff0c;比如可以用边缘特征可以区分脸和手…

Python错误分析与调试

在Python编程的过程中&#xff0c;我们难免会遇到各种各样的错误&#xff0c;而有效地分析和调试这些错误&#xff0c;能让我们的代码快速恢复正常运行&#xff0c;今天就来和大家聊聊Python中错误分析与调试的相关内容。 错误分析 Python中的错误大致可以分为语法错误和逻…

Browser-use:基于 Python 的智能浏览器自动化 AI 工具调研与实战

Browser-use&#xff1a;基于 Python 的智能浏览器自动化 AI 工具调研与实战 一、概述 Browser-use 是一个旨在将 AI “智能体”&#xff08;Agents&#xff09;与真实浏览器进行交互的 Python 库&#xff0c;可以轻松实现浏览器自动化。在配合 LLM&#xff08;如 GPT 系列&a…

网络空间安全(51)邮件函数漏洞

前言 邮件函数漏洞&#xff0c;特别是在PHP环境中使用mail()函数时&#xff0c;是一个重要的安全问题。 一、概述 在PHP中&#xff0c;mail()函数是一个用于发送电子邮件的内置函数。其函数原型为&#xff1a; bool mail ( string $to , string $subject , string $message [, …

LLaMA-Factory 数据集成从入门到精通

一、框架概述 LLaMA-Factory 框架通过Alpaca/Sharegpt双格式体系实现多任务适配&#xff0c;其中Alpaca专注结构化指令微调&#xff08;含SFT/DPO/预训练&#xff09;&#xff0c;Sharegpt支持多角色对话及多模态数据集成。核心配置依托 dataset_info.json 实现数据源映射、格…