Go 1.23新特性前瞻

news2024/11/18 23:25:59

2024年5月22日,Go 1.23版本[1]功能特性正式冻结,后续将只改bug,不增加新feature。

437f174e7c9e362a6f6a5869bd5dbc6a.png

对Go团队来说,这意味着开始了Go 1.23rc1的冲刺,对我们普通Gopher而言,这意味着是时候对Go 1.23新增的功能做一些前瞻了

在Go没有发布Go 1.23rc1之前,我们至少可以通过以下两种渠道体验Go 1.23的最新特性:

  • 通过go install安装tip版本;

  • 使用Go playground[2]在线体验。

注:关于Go tip的安装方法以及Go playground在线体验的详细说明,这里就不赘述了,《Go语言第一课》[3]专栏的“03|配好环境:选择一种最适合你的Go安装方法[4]”有系统全面的讲解,欢迎订阅阅读。

按照Go Release cycle[5],Go 1.23将于2024年8月发布!因此目前为时尚早,下面列出的有些变化最终不一定能进入到Go 1.23的最终版本中,有小概率被revert的可能或者推迟到下一个版本(Go 1.24),所以切记一切变更点要以最终Go 1.23版本发布时为准。

1. 语言变化

Go 1.23语言变化较少,除了range over func试验特性转正,再有就是几个悬而未决的spec变更。

1.1 range over func试验特性转正(61405[6])

Go 1.22版本[7]引入了range over func[8]试验特性,通过GOEXPERIMENT=rangefunc,可以实现函数迭代器。这一特性在Go 1.23版本正式转正,下面代码可以直接使用Go 1.23编译运行:

// go1.23-foresight/lang/range-over-function-iterator/main.go

package main

import "fmt"

func Backward[E any](s []E "E any") func(func(int, E) bool) {
 return func(yield func(int, E) bool) {
  for i := len(s) - 1; i >= 0; i-- {
   if !yield(i, s[i]) {
    return
   }
  }
  return
 }
}

func main() {
 sl := []string{"hello", "world", "golang"}
 for i, s := range Backward(sl) {
  fmt.Printf("%d : %s\n", i, s)
 }
}

使用Go 1.23运行上述示例:

$go run main.go                     
2 : golang
1 : world
0 : hello

range over func可以提供一种统一、高效的迭代方式, 为泛型后的自定义容器类提供统一的迭代接口,同时也可以替代部分现有API返回切片的做法, 改为通过迭代器的形式改进性能(通过编译器的优化),甚至还可以为函数式编程风格提供标准迭代机制。

rang over func机制的实现是通过编译器在源码层面的转换,其转换形式大致如下:

// 单循环变量
for x := range f1 {
 ...
}

将被转换为:

f1(func(x T) bool {
 ...
})

而另外一种常见的双循环变量形式的for range:

for expr1, expr2 = range f2 {
 ...
}

将被转换为:

f2(func(#p1 T1, #p2 T2) bool {
 expr1, expr2 = #p1, #p2
 ...
})

前提是:f1和f2分别要满足标准库中iter包中的下面函数原型形式:

// $GOROOT/src/iter/iter.go
type Seq[V any] func(yield func(V) bool) bool
type Seq2[K, V any] func(yield func(K, V) bool) bool

此外,for range循环体中如果有break,将被转换为f1/f2中的return false,而如果有continue,则会被转换为return true。当然这只是大致的形式,实际的转换远比这个要复杂很多,要考虑的情况也是十分复杂。更为具体、复杂的转换可以参考Go编译器的实现源码rewrite.go[9]

函数迭代器虽然转正,但肯定尚未成熟,后续还会有诸多问题(比如一些corner case)需要解决,比如Russ Cox新开的issue 65236[10]就在讨论是否允许忽略迭代变量;issue 65237[11]将跟踪spec中与range over func相关内容的变更。

1.2 spec:几个悬而未决的issue

  • 明确依赖常量的包级变量初始化时的次序(issue 66575)[12]

这个issue来自我提出的《Go 1.22引入的包级变量初始化次序问题[13]》,Go 1.23已经修正了该问题,并保持与Go 1.22之前的版本一致,但go spec[14]中尚未就此给出明确的说明。

  • 澄清"严格可比较"(strictly comparable)和"类型约束"(type constraints)等术语 (issue 59104)

  • [修改关于"类型参数是接口"的说明,避免引起混淆(issue 57310)](https://github.com/golang/go/issues/57310 "修改关于"类型参数是接口"的说明,避免引起混淆(issue 57310)")

  • 禁止匿名接口类型的循环定义(issue 56103)[15]

一些issue已经“跳票”多次,不能确定以上issue都能最终在Go 1.23得以解决!

2. 编译器与运行时

2.1 优化了PGO(Profile Guided Optimization)[16]带来的处理开销 (issue 58102[17])

Go社区发现启用PGO后,每个cmd/compile调用都会解析完整的PGO pprof配置文件,构建完整的权重图,然后确定与该包相关的内容。这类工作项有很多,并且随着Profile文件的大小和构建包的数量的扩展,构建开销也会增大。尤其是对于那些特别大的项目,PGO Profile很大,这可能会导致构建时间增加100%以上。

Go 1.23对这个问题进行了优化,PGO开销被降到了个位数百分比。

2.2 限制将来对linkname的使用(67401[18])

在Go语言中,//go:linkname指令可以用来链接到标准库或其他包中的未导出符号。比如我们想访问runtime包中的一个未导出函数,例如runtime.nanotime。这个函数返回当前时间的纳秒数。我们可以通过//go:linkname指令链接到这个符号。下面我用一个示例来演示一下这点:

// go1.23-foresight/compiler/golinkname/main.go
package main
  
import (
    "fmt"
    _ "unsafe" // 必须导入 unsafe 包以使用 //go:linkname
)

// 声明符号链接
//
//go:linkname nanotime runtime.nanotime
func nanotime() int64

func main() {
    // 调用未导出的 runtime.nanotime 函数
    fmt.Println("Current time in nanoseconds:", nanotime()) 
}

运行该示例:

$go run main.go
Current time in nanoseconds: 374424337532051

这种做法一般不推荐,因为它可能导致程序不稳定,并且未来版本的Go可能会改变内部实现(比如nanotime被改名或被删除),破坏你的代码。

Go团队已经意识到这一点,并发现现存开源代码中有很多代码都通过//go:linkname依赖Go项目的internal下的包或Go标准库的未导出符号。这显然不是Go团队想看到的事儿,于是Russ Cox发起issue 67401,旨在考虑限制对//go:linkname的使用。

该issue虽然在Go 1.23 milestone中,但最终是否能落在Go 1.23中还不确定,毕竟这样的调整会导致一些现存代码无法正常编译运行。

2.3 其他一些优化

  • 优化内存分配器的行为,减少了大内存(带有指针)分配时的长暂停 (issue 31222[19])

  • 修复Windows下time.Sleep的精度问题(issue 44343[20])

  • 增加了设置崩溃输出的API runtime/debug.SetCrashOutput(issue 42888[21])

  • 对内联器继续进行大修:重构优化 (issue 61502[22]),这是一个长期任务,估计后续版本还会继续。

3. 工具链

3.1 新增go telemetry子命令,改进go工具链的遥测能力 (issue 67111[23])

Russ Cox去年初就在个人博客上发布了四篇有关Go Telemetry的文章[24],在2023 GopherCon大会上,Russ Cox也谈到了Go Telemetry对基于数据驱动进行Go演进决策的重要性[25]。Russ Cox亲自创建的["all: add opt-in transparent telemetry to Go toolchain"](https://github.com/golang/go/issues/58894 ""all: add opt-in transparent telemetry to Go toolchain"")提案也被Go项目接受。

Go工具链中的telemetry是数据驱动的重要一环,最初golang.org/x/telemetry实验项目[26]被建立。在Go 1.23中,go工具链新增了go telemetry子命令,该子命令就是基于golang.org/x/telemetry实验项目,这也是Go团队实现某一个特性的一贯套路。

go telemetry子命令用法大致如下(以最终版本的doc为准):

go telemetry - 打印telemetry mode: on, off or local;
go telemetry on - 设置mode为on;即开启telemetry且上传遥测数据。
go telemetry local - 设置mode为local;即telemetry数据仅存储在本地,但不上传。
go telemetry off - 设置mode为off。即关闭telemetry
go clean -telemetry - 清理本地的遥测数据目录。

3.2 其他一些改变

  • go build(-json)支持以json形式输出构建结果(issue 62067[27]),让构建结果更结构化

  • 移除了对GOROOT_FINAL的支持 (issue 62047[28]),估计很多人不知道或完全没用过GOROOT_FINAL,我也是如此。

4. 标准库

4.1 Timer/Ticker变化

timer/ticker的stop/reset问题一直困扰Go团队,Go 1.23的两个重要fix期望能从根本上解决这个问题:

  • Timer/Ticker的GC不再需要Stop(issue 61542[29])

程序不再引用的Timer和Ticker将立即有资格进行垃圾回收,即使它们的Stop方法尚未被调用。Go的早期版本直到触发后才会收集未停止的Timer,并且从未收集未停止的Ticker。

  • Timer/Ticker的Stop/Reset后不再接收旧值(issue 37196[30])

与Timer或Ticker关联的计时器channel现在改为无缓冲的了,即容量为0 。此更改的主要效果是Go现在保证任何对Reset或Stop方法的调用,调用之前不会发送或接收任何陈旧值。 Go的早期版本使用带有缓冲区的channel,因此很难正确使用Reset和Stop。此更改的一个明显效果是计时器channel的len和cap现在返回0而不是1,这可能会影响轮询长度以确定是否在计时器channel上接收的程序。通过GODEBUG设置asynctimerchan=1可恢复异步通道行为。

4.2 新增unique包(issue 62483[31])

unique包的灵感来自于第三方包go4.org/intern[32],也是为了弥补Go语言缺乏对[interning](https://en.wikipedia.org/wiki/Interning_(computer_science "interning"))内置支持的空缺。

根据wikipedia的描述,interning是按需重复使用具有同等值对象的技术,减少创建新对象的动作。这种创建模式经常用于不同编程语言中的数和字符串,可以避免不必要的对象重复分配的开销。

Go unique包即是Go的interning机制的实现,unique包提供了一种高效的值去重和快速比较的机制,可以用于优化某些特定场景下的程序性能。

unique包提供给开发人员的API接口非常简单:Make用来创建Handle实例,Handle的方法Value用于获取值的拷贝。下面是一个使用unique包的典型示例:

// go1.23-foresight/lib/unique/main.go
package main

import (
 "fmt"
 "unique"
)

func main() {
 // 创建唯一Handle
 s1 := unique.Make("hello")
 s2 := unique.Make("world")
 s3 := unique.Make("hello")

 // s1和s3是相等的,因为它们是同一个字符串值
 fmt.Println(s1 == s3) // true
 fmt.Println(s1 == s2) // false

 // 从Handle获取原始值
 fmt.Println(s1.Value()) // hello
 fmt.Println(s2.Value()) // world
}

代码和输出结果都不难理解,这类就不赘述了。

4.3 函数迭代器相关

前面说过,函数迭代器转正了。标准库中有一些包立即就提供了一些便利的、可以与函数迭代器一起使用的函数,以slices、maps两个后加入Go标准库的泛型容器包为主。

其中slices包增加了:All、Values、Backward、Collect、AppendSeq、Sortted、SortedFunc、SortedStableFunc和Chunk。maps包增加了All、Keys、Values、Insert和Collect。

我们以slices包的All和Backward来构建一个示例,直观感受一下:

// go1.23-foresight/lib/slices/main.go

package main

import (
 "fmt"
 "slices"
)

func main() {
 sl := []string{"hello", "world", "golang"}

 for i, s := range slices.All(sl) {
  fmt.Printf("%d : %s\n", i, s)
 }

 for i, s := range slices.Backward(sl) {
  fmt.Printf("%d : %s\n", i, s)
 }
}

运行该示例:

$go run main.go
0 : hello
1 : world
2 : golang
2 : golang
1 : world
0 : hello

和以往一样,Go标准库是变化最多的一块儿,但篇幅有限,这里不便枚举,大家可以自行查看Go 1.23里程碑,选择自己关注的标准库变化,并深入研究。

5. 小结

本文主要预览了Go 1.23版本即将带来的新特性和变化。

首先在语言层面,range over func试验特性正式转正,提供统一高效的迭代方式;同时也会修复之前一些悬而未决的规范问题。

其次,在编译器和运行时方面,Go 1.23将优化PGO带来的开销,限制对linkname的使用,优化内存分配器和内联器等。工具链方面,新增telemetry子命令改进遥测能力。

标准库也有不少变化,比如Timer/Ticker的相关修复,新增unique包实现interning机制,以及为函数迭代器新增一些辅助函数。

Go 1.23的Release Notes的编写方式也做了调整,详细内容可参考我的公号文章《Go 1.23 Release Notes编写方式改进!》。

总的来说,Go 1.23包含了语法、编译器、运行时、工具链和标准库等多方面的改进,其中最主要集中在编译器性能优化、PGO特性增强、新编译器功能实现以及标准库增强等方面。

不过由于Go 1.23尚未发布,文中部分变化还可能被修改或推迟到下个版本。最终还是以正式发布版为准。文末也列出了一些相关资源链接,方便读者深入了解。

截至发文时,Go 1.23 milestone已经完成59%(https://github.com/golang/go/milestone/212),还有188个open的issue待解决。究竟Go 1.23最终会做出哪些改变,让我们拭目以待!

最后,感谢Go团队以及所有Go 1.23贡献者做出的伟大工作!

文本涉及的源码可以在这里[33]下载。

6. 参考资料

  • Go 1.23版本里程碑[34] - https://github.com/golang/go/milestone/212

  • Next Release Notes Draft[35] - https://tip.golang.org/doc/next

  • Go Release Dashboard[36] - https://dev.golang.org/release


Gopher部落知识星球[37]在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

cd4ef3e1e253941316bc8484cc308415.jpeg1945e3aca35b452a27e787d670cc7e94.png

d5252584f30d7080beefe895f2522fca.png441df58e53ff0cb07c9283cedb9905cb.jpeg

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址[38]:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) - https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx

  • 微博2:https://weibo.com/u/6484441286

  • 博客:tonybai.com

  • github: https://github.com/bigwhite

  • Gopher Daily归档 - https://github.com/bigwhite/gopherdaily

cbc05298d6420749856643829982caa4.jpeg

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

参考资料

[1] 

Go 1.23版本: https://github.com/golang/go/milestone/212

[2] 

Go playground: https://go.dev/play/

[3] 

《Go语言第一课》: http://gk.link/a/10AVZ

[4] 

03|配好环境:选择一种最适合你的Go安装方法: https://time.geekbang.org/column/article/427489

[5] 

Go Release cycle: https://go.dev/wiki/Go-Release-Cycle

[6] 

61405: https://github.com/golang/go/issues/61405

[7] 

Go 1.22版本: https://tonybai.com/2024/02/18/some-changes-in-go-1-22/

[8] 

range over func: https://go.dev/wiki/RangefuncExperiment

[9] 

Go编译器的实现源码rewrite.go: https://github.com/golang/go/blob/master/src/cmd/compile/internal/rangefunc/rewrite.go

[10] 

issue 65236: https://github.com/golang/go/issues/65236

[11] 

issue 65237: https://github.com/golang/go/issues/65237

[12] 

明确依赖常量的包级变量初始化时的次序(issue 66575): https://github.com/golang/go/issues/66575

[13] 

Go 1.22引入的包级变量初始化次序问题: https://tonybai.com/2024/03/29/the-issue-in-pkg-level-var-init-order-in-go-1-22/

[14] 

go spec: https://go.dev/ref/spec

[15] 

禁止匿名接口类型的循环定义(issue 56103): https://github.com/golang/go/issues/56103

[16] 

PGO(Profile Guided Optimization): https://go.dev/doc/pgo

[17] 

issue 58102: https://github.com/golang/go/issues/58102

[18] 

67401: https://github.com/golang/go/issues/67401

[19] 

issue 31222: https://github.com/golang/go/issues/31222

[20] 

issue 44343: https://github.com/golang/go/issues/44343

[21] 

issue 42888: https://github.com/golang/go/issues/42888

[22] 

issue 61502: https://github.com/golang/go/issues/61502

[23] 

issue 67111: https://github.com/golang/go/issues/67111

[24] 

四篇有关Go Telemetry的文章: https://research.swtch.com/telemetry

[25] 

Go Telemetry对基于数据驱动进行Go演进决策的重要性: https://tonybai.com/2023/12/10/go-changes/

[26] 

golang.org/x/telemetry实验项目: https://github.com/golang/telemetry

[27] 

issue 62067: https://github.com/golang/go/issues/62067

[28] 

issue 62047: https://github.com/golang/go/issues/62067

[29] 

issue 61542: https://github.com/golang/go/issues/61542

[30] 

issue 37196: https://github.com/golang/go/issues/37196

[31] 

issue 62483: https://github.com/golang/go/issues/62483

[32] 

go4.org/intern: https://github.com/go4org/intern

[33] 

这里: https://github.com/bigwhite/experiments/tree/master/go1.23-foresight

[34] 

Go 1.23版本里程碑: https://github.com/golang/go/milestone/212

[35] 

Next Release Notes Draft: https://tip.golang.org/doc/next

[36] 

Go Release Dashboard: https://dev.golang.org/release

[37] 

Gopher部落知识星球: https://public.zsxq.com/groups/51284458844544

[38] 

链接地址: https://m.do.co/c/bff6eed92687

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

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

相关文章

ad18学习笔记20:焊盘设置Solder Mask Expansion(阻焊层延伸)

【AD18新手入门】从零开始制造自己的PCB_ad18教程-CSDN博客 Altium Designer绘制焊盘孔(Pad孔)封装库的技巧,包括原理图封装和PCB封装_哔哩哔哩_bilibili 默认的焊盘中间是有个过孔的,单层焊盘(表贴烛盘)…

ARM学习(28)NXP 双coreMCU IMX1160学习

笔者最近接触到一块IMXRT1160的双core板子,特依次来记录学习一下 1、IMXRT1160 板子介绍 介绍一下NXP的Demo板子,是一个双core的板子,Cortexm7和Cortexm4,总计1MB的RAM空间,256KB的ROM空间,提供了丰富的内…

【GD32】05 - PWM 脉冲宽度调制

PWM PWM (Pulse Width Modulation) 是一种模拟信号电平的方法,它通过使用数字信号(通常是方波)来近似地表示模拟信号。在PWM中,信号的占空比(即高电平时间占整个周期的比例)被用来控制平均输出电压或电流。…

IDEA一键启动多个微服务

我们在做微服务项目开发的时候,每次刚打开IDEA,就需要把各个服务一个个依次启动,特别是服务比较多时,逐个点击不仅麻烦还费时。下面来说一下如何一键启动多个微服务。 操作步骤 点击Edit Configurations 2.点击“”,…

BSD盲区检测系统性能要求及试验方法

相关术语 盲区检测(bsd,blind spot detection)试验车辆(subject vehicle)目标车辆(target vehicle)横向距离(lateral distance):试验车车身最外缘(不包含外后视镜)与目标车辆车身最外缘(不包含外后视镜)之间的横向距离。 纵向距离(longitudinal distance):试验…

用windows server backup备份文件夹到网络共享文件夹并恢复

一、备份 开始 运行windows server backup,在右边的窗格中点击“备份计划” 选择备份配置 因为我们要备份的是一个文件夹,所以,选“自定义”,卷即为磁盘分区。 选择要备份的项 点击添加项目,可依次添加多个备份项目。 勾选需要…

职场思考-阅读专业与技能同步增长(12)

我们可以发现一个人“逆袭”的关键就是先要改变自己的思想,而机遇、资源都是外部条件。 改变思想无非也就几个途径: 一是阅读换脑,二是遇贵人点拨,三是社会“碰壁”后的反思并改正 对于职场进阶而言,阅读更是必要手段 …

知名专业定制线缆知名智造品牌推荐-精工电联:解决水下机器人线缆行业痛点的领航者

在科技日新月异的今天,精工电联作为高科技智能化产品及自动化设备专用连接线束和连接器配套服务商,致力于为高科技行业提供高品质、高性能的集成线缆和连接器定制服务。我们不仅是高品质定制线缆供应商,更是水下机器人线缆行业痛点的有效解决…

Dynamics CRM 修改新建记录的CreatedOn字段值

CRM在创建新记录时,一些系统属性例如创建者、创建时间是取当前创建记录的人以及当前的时间,而有时这些属性需要更改,例如创建时间,这个场景更多的用在数据迁移的时候,老数据有他的原始创建时间,不能因为迁移…

Linux网络-使用Tcp协议进行网络通信并通过网络接口实现远端翻译

文章目录 Tcp协议Tcp协议常见API接口1. int socket(int domain, int type, int protocol);2. int bind(int socket, const struct sockaddr *address, socklen_t address_len);struct sockaddr 3. int listen(int socket, int backlog);4. int accept(int socket, struct socka…

【设计模式】结构型-门面模式

前言 在软件开发中,设计模式是解决特定问题的经验总结,为开发者提供了一种可复用的解决方案。其中,门面模式(Facade Pattern)是一种结构型模式,旨在为复杂系统提供简化的接口,使客户端与系统之…

Java(十一)---String类型

文章目录 前言1.String类的重要性2.常用方法2.1.字符串的创建2.2.字符串的比较2.2.1.比较是否引用同一个对象2.2.2.boolean equals(Object anObject) 方法:2.2.3.int CompareTo(String s)2.2.4.int compareToIgnoreCase(String str) 方法: 2.3.字符串的查…

算法(十四)动态规划

算法概念 动态规划(Dynamic Programming)是一种分阶段求解的算法思想,通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(分治)的方式去解决。动态规划中有三个重点概念&#xff…

C 基础 - 预处理命令和基本语法详解

#include <stdio.h> //预处理指令int main() //函数 {printf("Hello, World!"); //输出语句return 0; //返回语句 } 目录 一.预处理指令 1.#define #ifdef #ifndef #if #else #elif #endif 2.#inlcude a.新增一个文件 b.#include c.运行结果 d.扩…

AI炒股-批量爬取网易财经的要闻板块

工作任务和目标&#xff1a;批量爬取网易财经的要闻板块 在class"tab_body current"的div标签中&#xff1b; 标题和链接在&#xff1a;<a href"https://www.163.com/dy/article/J2UIO5DD051188EA.html">华为急需找到“松弛感”</a> 第一步&…

【原创教程】MES服务器与成品打标机控制说明

1 实现的功能及应用的场合 MES即制造执行系统(manufacturing execution system,简称MES),即在加强MRP计划的执行功能,把MRP计划同车间作业现场控制,通过执行系统联系起来。 MES是一个生产管理智能化的一个系统,是用于生产时记录数据、产量等信息的智能管理系统。 该项…

WebGL画粗线

目录 前言 基本思路 求左右端点 实现 组织数据 顶点着色器计算端点坐标 效果 前言 WebGL绘制模式有点、线、面三种&#xff1b;通过点的绘制可以实现粒子系统等&#xff0c;通过线可以绘制一些连线关系&#xff1b;面就强大了&#xff0c;通过面&#xff0c;我们可以…

材质技术在AI去衣中的作用

随着人工智能技术的飞速发展&#xff0c;越来越多的应用场景开始涌现。其中&#xff0c;AI去衣技术作为一种新兴的图像处理技术&#xff0c;已经在很多领域得到了广泛的应用。而在AI去衣技术中&#xff0c;材质技术起到了至关重要的作用。本文将详细介绍材质技术在AI去衣中的作…

【前缀和 记忆化搜索】LeetCode1444. 切披萨的方案数

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 动态规划 记忆化搜索 LeetCode1444. 切披萨的方案数 给你一个 rows x cols 大小的矩形披萨和一个整数 k &#xff0c;矩形包含两种字符&#xff1a; ‘A’ &#xff…

生成式AI,在云端的绽放与盛开

编辑&#xff1a;阿冒 设计&#xff1a;沐由 毫无疑问&#xff0c;生成式AI已然成为当今技术发展和应用创新的重要引擎之一。 过去的一年多时间里&#xff0c;我们每个人都在目睹和见证着生成式AI是如何以移山倒海的力量&#xff0c;为诸多行业带来革命性乃至颠覆性的变革&…