当前位置: 首页 > news >正文

Golang语法、技巧和窍门

在这里插入图片描述

Golang简介

  • 命令式语言
  • 静态类型
  • 语法标记类似于C(但括号较少且没有分号),结构类似Oberon-2
  • 编译为本机代码(没有JVM)
  • 没有类,但有带有方法的结构
  • 接口
  • 没有实现继承。不过有type嵌入。
  • 函数是一等公民
  • 函数可以返回多个值
  • 支持闭包
  • 指针,但没有指针算术
  • 内置并发原语:Goroutines和Channels

基本语法

你好,世界

文件 hello.go

package mainimport "fmt"func main() {fmt.Println("Hello Go")
}
$ go run hello.go

运算符

算术运算符
运算符描述
+加法
-减法
*乘法
/除法
%取余
&位与
``
^位异或
&^位清除(非)
<<左移
>>右移
比较运算符
运算符描述
==等于
!=不等于
<小于
<=小于等于
>大于
>=大于等于
逻辑运算符
运算符描述
&&逻辑与
`
!逻辑非
其他
运算符描述
&取地址 / 创建指针
*解引用指针
<-发送 / 接收操作符(见下面的‘通道’部分)

声明

类型在标识符之后!

var foo int // declaration without initialization
var foo int = 42 // declaration with initialization
var foo, bar int = 42, 1302 // declare and init multiple vars at once
var foo = 42 // type omitted, will be inferred
foo := 42 // shorthand, only in func bodies, omit var keyword, type is always implicit
const constant = "This is a constant"// iota can be used for incrementing numbers, starting from 0
const (_ = iotaabc = 1 << iotad
)fmt.Println(a, b) // 1 2 (0 is skipped)fmt.Println(c, d) // 8 16 (2^3, 2^4)

函数

// a simple function
func functionName() {}// function with parameters (again, types go after identifiers)
func functionName(param1 string, param2 int) {}// multiple parameters of the same type
func functionName(param1, param2 int) {}// return type declaration
func functionName() int {return 42
}// Can return multiple values at once
func returnMulti() (int, string) {return 42, "foobar"
}
var x, str = returnMulti()// Return multiple named results simply by return
func returnMulti2() (n int, s string) {n = 42s = "foobar"// n and s will be returnedreturn
}
var x, str = returnMulti2()
函数作为值和闭包
func main() {// assign a function to a nameadd := func(a, b int) int {return a + b}// use the name to call the functionfmt.Println(add(3, 4))
}// Closures, lexically scoped: Functions can access values that were
// in scope when defining the function
func scope() func() int{outer_var := 2foo := func() int { return outer_var}return foo
}func another_scope() func() int{// won't compile because outer_var and foo not defined in this scopeouter_var = 444return foo
}// Closures
func outer() (func() int, int) {outer_var := 2inner := func() int {outer_var += 99 // outer_var from outer scope is mutated.return outer_var}inner()return inner, outer_var // return inner func and mutated outer_var 101
}
可变参数函数
func main() {fmt.Println(adder(1, 2, 3)) 	// 6fmt.Println(adder(9, 9))	// 18nums := []int{10, 20, 30}fmt.Println(adder(nums...))	// 60
}// By using ... before the type name of the last parameter you can indicate that it takes zero or more of those parameters.
// The function is invoked like any other function except we can pass as many arguments as we want.
func adder(args ...int) int {total := 0for _, v := range args { // Iterates over the arguments whatever the number.total += v}return total
}

内置类型

boolstringint  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptrbyte // alias for uint8rune // alias for int32 ~= a character (Unicode code point) - very Vikingfloat32 float64complex64 complex128

所有Go的预声明标识符都定义在builtin包中。

类型转换

var i int = 42
var f float64 = float64(i)
var u uint = uint(f)// alternative syntax
i := 42
f := float64(i)
u := uint(f)

  • 在每个源文件的顶部声明包
  • 可执行文件位于main包中
  • 约定:包的名称等于导入路径的最后一个部分(导入路径math/rand => 包rand
  • 大写标识符:导出的(可以从其他包中访问)
  • 小写标识符:私有的(不能从其他包中访问)

控制结构

判断
func main() {// Basic oneif x > 10 {return x} else if x == 10 {return 10} else {return -x}// You can put one statement before the conditionif a := b + c; a < 42 {return a} else {return a - 42}// Type assertion inside ifvar val interface{} = "foo"if str, ok := val.(string); ok {fmt.Println(str)}
}
循环
    // There's only `for`, no `while`, no `until`for i := 1; i < 10; i++ {}for ; i < 10;  { // while - loop}for i < 10  { // you can omit semicolons if there is only a condition}for { // you can omit the condition ~ while (true)}// use break/continue on current loop// use break/continue with label on outer loop
here:for i := 0; i < 2; i++ {for j := i + 1; j < 3; j++ {if i == 0 {continue here}fmt.Println(j)if j == 2 {break}}}there:for i := 0; i < 2; i++ {for j := i + 1; j < 3; j++ {if j == 1 {continue}fmt.Println(j)if j == 2 {break there}}}
条件
    // switch statementswitch operatingSystem {case "darwin":fmt.Println("Mac OS Hipster")// cases break automatically, no fallthrough by defaultcase "linux":fmt.Println("Linux Geek")default:// Windows, BSD, ...fmt.Println("Other")}// as with for and if, you can have an assignment statement before the switch valueswitch os := runtime.GOOS; os {case "darwin": ...}// you can also make comparisons in switch casesnumber := 42switch {case number < 42:fmt.Println("Smaller")case number == 42:fmt.Println("Equal")case number > 42:fmt.Println("Greater")}// cases can be presented in comma-separated listsvar char byte = '?'switch char {case ' ', '?', '&', '=', '#', '+', '%':fmt.Println("Should escape")}

数组, 切片, 遍历

数组
var a [10]int // declare an int array with length 10. Array length is part of the type!
a[3] = 42     // set elements
i := a[3]     // read elements// declare and initialize
var a = [2]int{1, 2}
a := [2]int{1, 2} //shorthand
a := [...]int{1, 2} // elipsis -> Compiler figures out array length
切片
var a []int                              // declare a slice - similar to an array, but length is unspecified
var a = []int {1, 2, 3, 4}               // declare and initialize a slice (backed by the array given implicitly)
a := []int{1, 2, 3, 4}                   // shorthand
chars := []string{0:"a", 2:"c", 1: "b"}  // ["a", "b", "c"]var b = a[lo:hi]	// creates a slice (view of the array) from index lo to hi-1
var b = a[1:4]		// slice from index 1 to 3
var b = a[:3]		// missing low index implies 0
var b = a[3:]		// missing high index implies len(a)
a =  append(a,17,3)	// append items to slice a
c := append(a,b...)	// concatenate slices a and b// create a slice with make
a = make([]byte, 5, 5)	// first arg length, second capacity
a = make([]byte, 5)	// capacity is optional// create a slice from an array
x := [3]string{"Лайка", "Белка", "Стрелка"}
s := x[:] // a slice referencing the storage of x
数组和切片的操作

len(a) 返回数组/切片的长度。这是一个内置函数,而不是数组的属性/方法。

// loop over an array/a slice
for i, e := range a {// i is the index, e the element
}// if you only need e:
for _, e := range a {// e is the element
}// ...and if you only need the index
for i := range a {
}// In Go pre-1.4, you'll get a compiler error if you're not using i and e.
// Go 1.4 introduced a variable-free form, so that you can do this
for range time.Tick(time.Second) {// do it once a sec
}

哈希表

m := make(map[string]int)
m["key"] = 42
fmt.Println(m["key"])delete(m, "key")elem, ok := m["key"] // test if key "key" is present and retrieve it, if so// map literal
var m = map[string]Vertex{"Bell Labs": {40.68433, -74.39967},"Google":    {37.42202, -122.08408},
}// iterate over map content
for key, value := range m {
}

结构体

Go中没有类,只有结构体。结构体可以拥有方法。

// A struct is a type. It's also a collection of fields// Declaration
type Vertex struct {X, Y float64
}// Creating
var v = Vertex{1, 2}
var v = Vertex{X: 1, Y: 2} // Creates a struct by defining values with keys
var v = []Vertex{{1,2},{5,2},{5,5}} // Initialize a slice of structs// Accessing members
v.X = 4// You can declare methods on structs. The struct you want to declare the
// method on (the receiving type) comes between the the func keyword and
// the method name. The struct is copied on each method call(!)
func (v Vertex) Abs() float64 {return math.Sqrt(v.X*v.X + v.Y*v.Y)
}// Call method
v.Abs()// For mutating methods, you need to use a pointer (see below) to the Struct
// as the type. With this, the struct value is not copied for the method call.
func (v *Vertex) add(n float64) {v.X += nv.Y += n
}

匿名结构体: 比使用 map[string]interface{} 更经济和更安全。

point := struct {X, Y int
}{1, 2}

指针

p := Vertex{1, 2}  // p is a Vertex
q := &p            // q is a pointer to a Vertex
r := &Vertex{1, 2} // r is also a pointer to a Vertex// The type of a pointer to a Vertex is *Vertexvar s *Vertex = new(Vertex) // new creates a pointer to a new struct instance

接口

// interface declaration
type Awesomizer interface {Awesomize() string
}// types do *not* declare to implement interfaces
type Foo struct {}// instead, types implicitly satisfy an interface if they implement all required methods
func (foo Foo) Awesomize() string {return "Awesome!"
}

嵌入

Go中没有子类化。相反,有接口和结构体嵌入。

// ReadWriter implementations must satisfy both Reader and Writer
type ReadWriter interface {ReaderWriter
}// Server exposes all the methods that Logger has
type Server struct {Host stringPort int*log.Logger
}// initialize the embedded type the usual way
server := &Server{"localhost", 80, log.New(...)}// methods implemented on the embedded struct are passed through
server.Log(...) // calls server.Logger.Log(...)// the field name of the embedded type is its type name (in this case Logger)
var logger *log.Logger = server.Logger

错误

Go中没有异常处理。相反,可能产生错误的函数只是声明了一个额外的返回值,类型为error。这是error接口:

// The error built-in interface type is the conventional interface for representing an error condition,
// with the nil value representing no error.
type error interface {Error() string
}

这是一个示例:

func sqrt(x float64) (float64, error) {if x < 0 {return 0, errors.New("negative value")}return math.Sqrt(x), nil
}func main() {val, err := sqrt(-1)if err != nil {// handle errorfmt.Println(err) // negative valuereturn}// All is good, use `val`.fmt.Println(val)
}

并发

协程

Goroutines是轻量级线程(由Go管理,而不是操作系统线程)。go f(a, b)启动一个新的goroutine来运行f(假设f是一个函数)。

// just a function (which can be later started as a goroutine)
func doStuff(s string) {
}func main() {// using a named function in a goroutinego doStuff("foobar")// using an anonymous inner function in a goroutinego func (x int) {// function body goes here}(42)
}

通道

ch := make(chan int) // create a channel of type int
ch <- 42             // Send a value to the channel ch.
v := <-ch            // Receive a value from ch// Non-buffered channels block. Read blocks when no value is available, write blocks until there is a read.// Create a buffered channel. Writing to a buffered channels does not block if less than <buffer size> unread values have been written.
ch := make(chan int, 100)close(ch) // closes the channel (only sender should close)// read from channel and test if it has been closed
v, ok := <-ch// if ok is false, channel has been closed// Read from channel until it is closed
for i := range ch {fmt.Println(i)
}// select blocks on multiple channel operations, if one unblocks, the corresponding case is executed
func doStuff(channelOut, channelIn chan int) {select {case channelOut <- 42:fmt.Println("We could write to channelOut!")case x := <- channelIn:fmt.Println("We could read from channelIn")case <-time.After(time.Second * 1):fmt.Println("timeout")}
}
通道原理
  • 向空通道发送会永远阻塞

    var c chan string
    c <- "Hello, World!"
    // fatal error: all goroutines are asleep - deadlock!
    
  • 从空通道接收会永远阻塞。

    var c chan string
    fmt.Println(<-c)
    // fatal error: all goroutines are asleep - deadlock!
    
  • 向已关闭的通道发送会引发恐慌。

    var c = make(chan string, 1)
    c <- "Hello, World!"
    close(c)
    c <- "Hello, Panic!"
    // panic: send on closed channel
    
  • 从已关闭的通道接收会立即返回零值。

    var c = make(chan int, 2)
    c <- 1
    c <- 2
    close(c)
    for i := 0; i < 3; i++ {fmt.Printf("%d ", <-c)
    }
    // 1 2 0
    

打印

fmt.Println("Hello, 你好, नमस्ते, Привет, ᎣᏏᏲ") // basic print, plus newline
p := struct { X, Y int }{ 17, 2 }
fmt.Println( "My point:", p, "x coord=", p.X ) // print structs, ints, etc
s := fmt.Sprintln( "My point:", p, "x coord=", p.X ) // print to string variablefmt.Printf("%d hex:%x bin:%b fp:%f sci:%e",17,17,17,17.0,17.0) // c-ish format
s2 := fmt.Sprintf( "%d %f", 17, 17.0 ) // formatted print to string variablehellomsg := `"Hello" in Chinese is 你好 ('Ni Hao')"Hello" in Hindi is नमस्ते ('Namaste')
` // multi-line string literal, using back-tick at beginning and end

反射

类型切换

类型切换类似于常规的switch语句,但类型切换中的情况指定要与给定接口值持有的值的类型进行比较的类型,而不是值。

func do(i interface{}) {switch v := i.(type) {case int:fmt.Printf("Twice %v is %v\n", v, v*2)case string:fmt.Printf("%q is %v bytes long\n", v, len(v))default:fmt.Printf("I don't know about type %T!\n", v)}
}func main() {do(21)do("hello")do(true)
}

片段

文件嵌入

Go程序可以使用"embed"包嵌入静态文件,如下所示:

package mainimport ("embed""log""net/http"
)// content holds the static content (2 files) for the web server.
//go:embed a.txt b.txt
var content embed.FSfunc main() {http.Handle("/", http.FileServer(http.FS(content)))log.Fatal(http.ListenAndServe(":8080", nil))
}

完整的Playground示例

HTTP服务器

package mainimport ("fmt""net/http"
)// define a type for the response
type Hello struct{}// let that type implement the ServeHTTP method (defined in interface http.Handler)
func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprint(w, "Hello!")
}func main() {var h Hellohttp.ListenAndServe("localhost:4000", h)
}// Here's the method signature of http.ServeHTTP:
// type Handler interface {
//     ServeHTTP(w http.ResponseWriter, r *http.Request)
// }

相关文章:

Golang语法、技巧和窍门

Golang简介 命令式语言静态类型语法标记类似于C&#xff08;但括号较少且没有分号&#xff09;&#xff0c;结构类似Oberon-2编译为本机代码&#xff08;没有JVM&#xff09;没有类&#xff0c;但有带有方法的结构接口没有实现继承。不过有type嵌入。函数是一等公民函数可以返…...

Grander因果检验(格兰杰)原理+操作+解释

笔记来源&#xff1a; 1.【传送门】 2.【传送门】 前沿原理介绍 Grander因果检验是一种分析时间序列数据因果关系的方法。 基本思想在于&#xff0c;在控制Y的滞后项 (过去值) 的情况下&#xff0c;如果X的滞后项仍然有助于解释Y的当期值的变动&#xff0c;则认为 X对 Y产生…...

Python-Flask:编写自动化连接demo脚本:v1.0.0

主函数&#xff1a; # _*_ Coding : UTF-8 _*_ # Time : 13:14 # Author : YYZ # File : Flask # Project : Python_Project_爬虫 import jsonfrom flask import Flask,request,jsonify import sshapi Flask(__name__)# methods: 指定请求方式 接口解析参数host host_info[…...

kafka客户端应用参数详解

一、基本客户端收发消息 Kafka提供了非常简单的客户端API。只需要引入一个Maven依赖即可&#xff1a; <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka_2.13</artifactId><version>3.4.0</version></depend…...

Apache Doris 行列转换可以这样玩

行列转换在做报表分析时还是经常会遇到的&#xff0c;今天就说一下如何实现行列转换吧。 行列转换就是如下图所示两种展示形式的互相转换 1. 行转列 我们来看一个简单的例子&#xff0c;我们要把下面这个表的数据&#xff0c;转换成图二的样式 image-20230914151818953.png …...

【Qt图形视图框架】自定义QGraphicsItem和QGraphicsView,实现鼠标(移动、缩放)及键盘事件、右键事件

自定义QGraphicsItem和QGraphicsView 说明示例myitem.hmyitem.cppmyview.hmyview.cpp调用main.cpp 效果 说明 在使用Qt的图形视图框架实现功能时&#xff0c;一般会在其基础上进行自定义功能实现。 如&#xff1a;滚轮对场景的缩放&#xff0c;鼠标拖动场景中的项&#xff0c;…...

C语言结构体指针学习

结构体变量存放内存中&#xff0c;也有起始地址&#xff0c;定义一个变量来存放这个地址&#xff0c;那这个变量就是结构体指针&#xff1b; typedef struct mydata{int a1;int a2;int a3; }mydata;void CJgtzzView::OnDraw(CDC* pDC) {CJgtzzDoc* pDoc GetDocument();ASSERT…...

华为云云耀云服务器L实例评测|部署在线轻量级备忘录 memos

华为云云耀云服务器L实例评测&#xff5c;部署在线轻量级备忘录 memos 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 产品优势1.3 应用场景1.4 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 memos3.1 memos介绍3.2 Docker 环境搭建…...

详解Avast Driver Updater:电脑驱动更新工具的利器还是多余的软件?

亲爱的读者朋友们&#xff0c;你是不是经常为电脑的驱动问题而烦恼&#xff1f;如果是的话&#xff0c;你可能会对这款软件——Avast Driver Updater 电脑驱动更新工具感兴趣。但在你决定尝试之前&#xff0c;不妨先和我一起深入探讨一下它的优点、缺点以及它适用的使用场景。 …...

大数据Flink(九十五):DML:Window TopN

文章目录 DML:Window TopN DML:Window TopN Window TopN 定义(支持 Streaming):Window TopN 是一种特殊的 TopN,它的返回结果是每一个窗口内的 N 个最小值或者最大值。 应用场景...

使用OKHttpClient访问网络

使用OKHttpClient前要引入依赖&#xff1a; 在build.gradle(Moduel :app)中添加 implementation com.squareup.okhttp3:okhttp:3.14.1 implementation com.squareup.okhttp3:logging-interceptor:3.14.1 implementation com.squareup.okio:okio:1.6.0 1. GET&#xff08;同步…...

maui 开发AMD CPU踩的坑。

刚换的 amd R7735HS 笔记本&#xff0c;8核16线程&#xff0c;32GB内存。性能得实强悍 。 当需要发布iOS版本时发现&#xff0c;我没有macos &#xff0c;那就安装个vmware 吧。看了一下Apple 要求以后的发布的APP需要以xcode14.3或以后版本开发的版本&#xff0c;但xcode14.3…...

宝塔反代openai官方API接口详细教程,502 Bad Gateway问题解决

一、前言 宝塔反代openai官方API接口详细教程&#xff0c;实现国内使用ChatGPT502 Bad Gateway问题解决&#xff0c; 此方法最简单快捷&#xff0c;没有复杂步骤&#xff0c;不容易出错&#xff0c;即最简单&#xff0c;零代码、零部署的方法。 二、实现前提 一台海外VPS服务…...

【leetocde】128. 最长连续序列

给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1&#xff1a; 输入&#xff1a;nums [100,4,200,1,3,2] 输出&#xff1a;4 …...

【Vue3】动态 class 类

如果你想在 Vue.js 中动态设置元素的 class 类名&#xff0c;你可以使用以下两种主要方式&#xff1a; 绑定一个动态的 class 对象&#xff1a;你可以使用 v-bind 或简写的 : 来绑定一个包含类名的对象&#xff0c;其中类名的键是类名字符串&#xff0c;值是一个布尔值或计算属…...

【Redis】redis基本数据类型详解(String、List、Hash、Set、ZSet)

目录 RedisString(字符串)List(列表)Hash(字典)Set(集合)ZSet(有序集合) Redis Redis有5种基本的数据结构&#xff0c;分别为&#xff1a;string&#xff08;字符串&#xff09;、list&#xff08;列表&#xff09;、set&#xff08;集合&#xff09;、hash&#xff08;哈希&a…...

ubuntu源码安装aria2

github:GitHub - aria2/aria2: aria2 is a lightweight multi-protocol & multi-source, cross platform download utility operated in command-line. It supports HTTP/HTTPS, FTP, SFTP, BitTorrent and Metalink. 发行说明&#xff1a;GitHub - aria2/aria2 at releas…...

【多任务案例:猫狗脸部定位与分类】

【猫狗脸部定位与识别】 1 引言2 损失函数3 The Oxford-IIIT Pet Dataset数据集4 数据预处理4 创建模型输入5 自定义数据集加载方式6 显示一批次数据7 创建定位模型8 模型训练9 绘制损失曲线10 模型保存与预测 1 引言 猫狗脸部定位与识别分为定位和识别&#xff0c;即定位猫狗…...

.Net 锁的介绍

在.NET中,有多种锁机制可用于多线程编程,用来确保线程安全和共享资源的同步。以下是.NET中常见的锁机制: 1. **Monitor(互斥锁):** `Monitor` 是.NET中最基本的锁机制之一。它使用 `lock` 关键字实现,可以确保在同一时刻只有一个线程能够访问被锁定的代码块。`Monitor`…...

Office 2021 小型企业版商用办公软件评测:提升工作效率与协作能力的专业利器

作为一名软件评测人员&#xff0c;我将为您带来一篇关于 Office 2021 小型企业版商用办公软件的评测文章。在这篇评测中&#xff0c;我将从实用性、使用场景、优点和缺点等多个方面对该软件进行客观分析&#xff0c;在专业角度为您揭示它的真正实力和潜力。 一、实用性&#xf…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...