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

[golang gin框架] 2.Gin HTML模板渲染以及模板语法,自定义模板函数,静态文件服务

一.Gin HTML 模板渲染

  1. 全部模板放在一个目录里面的配置方法

首先在项目根目录新建 templates 文件夹,然后在文件夹中新建 对应的index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>这是一个 html 模板</h1>
<h3>{{.title}}</h3>
</body>
</html>

2.Gin 框架中使用 c.HTML 可以渲染模板,渲染模板前需要使用 LoadHTMLGlob()或者LoadHTMLFiles()方法加载模板

package main
import ( "net/http""github.com/gin-gonic/gin"
)func main() {//初始化路由router := gin.Default()//加载templates中所有模板文件, 使用不同目录下名称相同的模板,注意:一定要放在配置路由之前才得行router.LoadHTMLGlob("templates/*")//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")router.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "index.html", gin.H{ "title": "首页", })})router.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "index.html", map[string]interface{}{ "title": "前台首页"})})router.Run(":8080")
}
  1. 模板放在不同目录里面的配置方法

目录如下:
Gin 框架中如果不同目录下面有同名模板的话我们需要使用下面方法加载模板
注意:定义模板的时候需要通过 define 定义名称
//templates/admin/index.html
<!-- 相当于给模板定义一个名字 define end 成对出现-->{{ define "admin/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>后台模板</h1>
<h3>{{.title}}</h3>
</body>
</html>
{{ end }}
templates/default/index.html
<!-- 相当于给模板定义一个名字 define end 成对出现-->{{ define "default/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>前台模板</h1>
<h3>{{.title}}</h3>
</body>
</html>
{{end}}
代码如下:
package main
import ( "net/http"
"github.com/gin-gonic/gin"
)
func main() {router := gin.Default()router.LoadHTMLGlob("templates/**/*")router.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "default/index.html", gin.H{ "title": "前台首页", })})router.GET("/admin", func(c *gin.Context) {c.HTML(http.StatusOK, "admin/index.html", gin.H{ "title": "后台首页", })})router.Run(":8080")
}
注意:如果模板在多级目录里面的话需要这样配置 r.LoadHTMLGlob("templates/**/**/*") /**
表示目录

3.Gin 模板基本语法

(1)、{{.}} 输出数据

模板语法都包含在{{和}}中间,其中{{.}}中的点表示当前对象,当传入一个结构体对象时,可以根据.来访问结构体的对应字段。例如:

package mainimport ( "net/http""github.com/gin-gonic/gin"
)type UserInfo struct {Name stringGender stringAge int
}
func main() {router := gin.Default()router.LoadHTMLGlob("templates/**/*")user := UserInfo{Name: "张三",Gender: "男", Age: 18, }router.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "default/index.html", map[string]interface{}{ "title": "前台首页", "user": user, })})router.Run(":8080")
}

模板 <!-- 相当于给模板定义一个名字 define end 成对出现-->

{{ define "default/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>前台模板</h1>
<h3>{{.title}}</h3>
<h4>{{.user.Name}}</h4>
<h4>{{.user.Age}}</h4>
</body>
</html>
{{end}}

(2).注释

{{/* a comment */}}
注释,执行时会忽略,可以多行。注释不能嵌套,并且必须紧贴分界符始止

(3).变量

还可以在模板中声明变量,用来保存传入模板的数据或其他语句生成的结果,具体语法
如下:
<h4>{{$obj := .title}}</h4>
<h4>{{$obj}}</h4>

(4).移除空格

有时候在使用模板语法的时候会不可避免的引入一下空格或者换行符,这样模板最终渲
染出来的内容可能就和想的不一样,这个时候可以使用{{-语法去除模板内容左侧的所有
空白符号, 使用-}}去除模板内容右侧的所有空白符号,例如:
{{- .Name -}}
注意:-要紧挨{{和}},同时与模板值之间需要使用空格分隔

(5).比较函数

布尔函数会将任何类型的零值视为假,其余视为真.
下面是定义为函数的二元比较运算的集合

eq

如果 arg1 == arg2 则返回真

ne

如果 arg1 != arg2 则返回真

lt

如果 arg1 < arg2 则返回真

le

如果 arg1 <= arg2 则返回真

gt

如果 arg1 > arg2 则返回真

ge

如果 arg1 >= arg2 则返回真

(6).条件判断

Go 模板语法中的条件判断有以下几种
{{if pipeline}} T1 
{{end}}{{if pipeline}} T1 
{{else}} T0 
{{end}}{{if pipeline}} T1 
{{else if pipeline}} T0 
{{end}}{{if gt .score 60}}及格
{{else}}不及格
{{end}}{{if gt .score 90}}优秀
{{else if gt .score 60}}及格
{{else}}不及格
{{end}}

(6).range

Go 的模板语法中使用 range 关键字进行遍历,有以下两种写法,其中 pipeline 的值必须是数
组、切片、字典或者通道
{{range $key,$value := .obj}}{{$value}}
{{end}}
如果 pipeline 的值其长度为 0,不会有任何输出
{{$key,$value := .obj}}{{$value}}
{{else}}pipeline 的值其长度为 0
{{end}}
如果 pipeline 的值其长度为 0,则会执行 T0
router.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "default/index.html", map[string]interface{}{ "hobby": []string{"吃饭", "睡觉", "写代码"}, })
})
{{range $key,$value := .hobby}}<p>{{$value}}</p>
{{end}}

(7).with

user := UserInfo{Name: "张三", Gender: "男", Age: 18, 
}
router.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "default/index.html", map[string]interface{}{ "user": user, })
})

以前要输出数据:

<h4>{{.user.Name}}</h4>
<h4>{{.user.Gender}}</h4>
<h4>{{.user.Age}}</h4>

现在要输出数据:

{{with .user}}<h4>姓名:{{.Name}}</h4><h4>性别:{{.Gender}}</h4><h4>年龄:{{.Age}}</h4>
{{end}}
相当于 var .=.user

(8).预定义函数

执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典,一
般不在模板内定义函数,而是使用 Funcs 方法添加函数到模板里,预定义的全局函数如下:

and

函数返回它的第一个 empty 参数或者最后一个参数;

就是说"and x y"等价于"if x then y else x";所有参数都会执行

or

返回第一个非 empty 参数或者最后一个参数;

亦即"or x y"等价于"if x then x else y";所有参数都会执行

not

返回它的单个参数的布尔值的否定

len

返回它的参数的整数类型长度

index

执行结果为第一个参数以剩下的参数为索引/键指向的值;

如"index x 1 2 3"返回 x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典

print

即 fmt.Sprint

printf

即 fmt.Sprintf

println

即 fmt.Sprintln

html

返回与其参数的文本表示形式等效的转义 HTML。

这个函数在 html/template 中不可用

urlquery

以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。

这个函数在 html/template 中不可用

js

返回与其参数的文本表示形式等效的转义 JavaScript

call

执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函

数的参数;

如"call .X.Y 1 2"等价于 go 语言里的 dot.X.Y(1, 2);

其中 Y 是函数类型的字段或者字典的值,或者其他类似情况;

call 的第一个参数的执行结果必须是函数类型的值(和预定义函数如 print 明显不同);

该函数类型值必须有 1 到 2 个返回值,如果有 2 个则后一个必须是 error 接口类型;

如果有 2 个返回值的方法返回的 error 非 nil,模板执行会中断并返回给调用模板执行者

该错误

{{len .title}}
{{index .hobby 2}}

(9).自定义模板函数

package mainimport ( "fmt""html/template""net/http""time""github.com/gin-gonic/gin"
)func formatAsDate(t time.Time) string {year, month, day := t.Date()return fmt.Sprintf("%d/%02d/%02d", year, month, day)
}func main() {router := gin.Default()//注册全局模板函数 注意顺序,注册模板函数需要在加载模板上面router.SetFuncMap(template.FuncMap{ "formatDate": formatAsDate,})//加载模板router.LoadHTMLGlob("templates/**/*")router.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "default/index.html", map[string]interface{}{ "title": "前台首页", "now": time.Now(),})})router.Run(":8080")
}
{{.now | formatDate}}
//或者
{{formatDate .now }}

4.嵌套 template

(1).新建 templates/deafult/page_header.html

{{ define "default/page_header.html" }}
<h1>这是一个头部</h1>
{{end}}

(2).外部引入

注意:
1).引入的名字为 page_header.html 中定义的名字
2).引入的时候注意最后的点(.)
{{template "default/page_header.html" .}}
<!-- 相当于给模板定义一个名字 define end 成对出现-->
{{ define "default/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{{template "default/page_header.html" .}}
</body>
</html>
{{end}}

二.静态文件服务

当渲染的HTML 文件中引用了静态文件时,需要配置静态 web 服务r.Static("/static", "./static"),前面的/static 表示路由,后面的./static 表示路径
func main() {r := gin.Default()r.Static("/static", "./static")r.LoadHTMLGlob("templates/**/*")// ... r.Run(":8080")
}
<link rel="stylesheet" href="/static/css/base.css" />

案例目录如下:

代码如下:

main.go

package mainimport ("github.com/gin-gonic/gin""html/template""net/http""time"
)type Article struct {Title   string `json:"title"`Content string `json:"
"`
}//时间戳转换成日期函数
func UnixToTime(timestamp int) string  {t := time.Unix(int64(timestamp), 0)return t.Format("2006-01-02 15:04:05")
}func Println(str1 string, str2 string) string  {return str1 + str2
}func main() {//初始化路由r := gin.Default()//自定义模板函数,必须在r.LoadHTMLGlob前面r.SetFuncMap(template.FuncMap{"UnixToTime":UnixToTime, //注册模板函数"Println": Println,})//加载templates中所有模板文件, 使用不同目录下名称相同的模板,注意:一定要放在配置路由之前才得行r.LoadHTMLGlob("templates/**/*")//配置静态web目录 第一个参数表示路由,第二个参数表示映射的目录r.Static("/static", "./static")//配置路由//前台路由r.GET("/", func(c *gin.Context) {//渲染模板文件c.HTML(http.StatusOK, "default/index.html", gin.H{"title": "首页","score": 88,"hobby": []string{"吃饭", "睡觉", "打豆豆"}, // 切片"newList":[]interface{}{  // 接口&Article{Title:   "新闻标题1",Content: "新闻内容1",},&Article{Title:   "新闻标题2",Content: "新闻内容2",},},"testSlice":[]string{}, // 空数组/空切片"news": &Article{ // 结构体Title:   "新闻标题3",Content: "新闻内容3",},"date": 1672648334,})})r.GET("/news", func(c *gin.Context) {news := &Article{Title:   "新闻标题",Content: "新闻内容",}c.HTML(http.StatusOK, "default/news.html", gin.H{"title": "新闻详情","news":  news,})})//后台路由r.GET("/admin", func(c *gin.Context) {//渲染模板文件c.HTML(http.StatusOK, "admin/index.html", gin.H{"title": "后台首页",})})r.GET("/admin/news", func(c *gin.Context) {news := &Article{Title:   "后台新闻标题",Content: "后台新闻内容",}c.HTML(http.StatusOK, "admin/news.html", gin.H{"title": "后台新闻详情","news":  news,})})r.Run() // 启动一个web服务
}

templates/admin/index.html

<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "admin/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>后台首页</title>
</head>
<body>
<h2>{{.title}}</h2>
</body>
</html>
{{ end }}

templates/admin/news.html

{{ define "admin/news.html" }}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>后台新闻详情</title>
</head>
<body>
<h2>{{.title}}</h2>
</body>
</html>
{{ end }}

templates/default/index.html

<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "default/index.html" }}<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="/static/css/base.css"><title>首页</title></head><body>{{ template "public/page_header.html" .}}<h2>{{.title}}</h2><img src="/static/images/test.png"><!-- 定义变量 把后台的变量赋值给$t -->{{ $t := .title}}<!-- 显示$t --><h4> {{ $t }}</h4><!-- if判断 -->{{if gt .score 90}}<div>优秀</div><br/>{{else if gt .score 80}}<div>良好</div><br/>{{else if gt .score 70}}<div>可以</div><br/>{{ else }}<div>合格</div><br/>{{end}}<!-- 循环数据 --><ul><!-- 循环切片 -->{{range $k, $v := .hobby}}<li>{{$k}} => {{$v}}</li>{{end}}</ul><ul><!-- 循环结构体 -->{{range $k, $v := .newList}}<li>{{$k}} => {{$v.Title}} --- {{$v.Content}}</li>{{end}}</ul><ul><!-- 循环空数组/切片 判断 -->{{range $k, $v := .testSlice}}<li>{{$k}} => {{$v.Title}} --- {{$v.Content}}</li>{{else}}<li>空数据</li>{{end}}</ul><ul><!-- with 解析结构体-->{{with .news}}<li>{{.Title}} => {{.Content}}</li>{{end}}</ul><h4><!--预定义函数 -->{{.title}}的长度为{{len .title}}</h4><h4><!--自定义函数 -->{{UnixToTime .date}}{{Println .title .news.Title}}</h4><!-- 嵌套 template -->{{ template "public/page_footer.html" .}}</body></html>
{{end}}

templates/default/news.html

<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "default/news.html" }}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>news</title>
</head>
<body>
{{ template "public/page_header.html" .}}<link rel="stylesheet" href="static/css/base.css">
<h2>{{.title}}</h2>
<h4>{{.news.Title}}{{.news.Content}}
</h4>
{{ template "public/page_footer.html" .}}
</body>
</html>
{{ end }}    

templates/public/page_footer.html

<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "public/page_footer.html" }}<h4>公共的底部</h4>
{{end}}

templates/public/page_header.html

<!-- 相当于给模板定义一个名字, define end 必须成对出现 -->
{{ define "public/page_header.html" }}<h1>公共的 --- {{.title}}</h1>
{{end}}

[上一节][golang gin框架] 1.Gin环境搭建,程序的热加载,路由GET,POST,PUT,DELETE

相关文章:

[golang gin框架] 2.Gin HTML模板渲染以及模板语法,自定义模板函数,静态文件服务

一.Gin HTML 模板渲染全部模板放在一个目录里面的配置方法首先在项目根目录新建 templates 文件夹&#xff0c;然后在文件夹中新建 对应的index.html<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta http…...

数据仓库层Repository(CrudRepository、PagingAndSortingRepository、JpaRepository)

什么是数据仓库层Repository&#xff1f; 数据仓库接口的作用&#xff1a;Repository原意指的是仓库&#xff0c;即数据仓库的意思。Repository居于业务层和数据层之间&#xff0c;将两者隔离开来&#xff0c;在它的内部封装了数据查询和存储的逻辑。 Repository接口&#xff…...

大数据技术架构(组件)33——Spark:Spark SQL--Join Type

2.2.2、Join Type2.2.2.1、Broadcast Hash Join (Not Shuffled)就是常说的MapJoin,join操作在map端进行的。场景&#xff1a;join的其中一张表要很小&#xff0c;可以放到Driver或者Executor端的内存中。原理:1、将小表的数据广播到所有的Executor端&#xff0c;利用collect算子…...

Linux: bash起后台进程引发的僵尸进程

1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任何承诺。 2. 案例 原来的故事是 这样 的&#xff0c;感兴趣的读者可以直接前往。我从中截取了一段重现故事中问题的代码&#xff08;对原代码做了小小调整&a…...

网络安全攻防中,Rock-ON自动化的多功能网络侦查工具,Burpsuite被动扫描流量转发

网络安全攻防中&#xff0c;Rock-ON自动化的多功能网络侦查工具&#xff0c;Burpsuite被动扫描流量转发。 #################### 免责声明&#xff1a;工具本身并无好坏&#xff0c;希望大家以遵守《网络安全法》相关法律为前提来使用该工具&#xff0c;支持研究学习&#xff…...

电子技术——共模抑制

电子技术——共模抑制 我们在之前学习过&#xff0c;无论是MOS还是BJT的差分输入对&#xff0c;共模信号并不会改变漏极电流的大小&#xff0c;因此我们说差分输入对共模信号无响应。但是实际上由于各种客观非理想因素&#xff0c;例如电流源有限阻抗等&#xff0c;此时共模是影…...

对KMP简单的理解

声明&#xff1a;下边的例子均表示下标从1开始的数组 ne数组的定义&#xff1a; next[i] 就是使子串 s[1…i] 有最长相等前后缀的前缀的最后一位的下标。ne[i]也可以表示相等子串的长度 准备执行jne[j]时&#xff0c; 表示当前s[i]!p[j1] , 如果ne[j]1 &#xff0c;那么下…...

Hibernate不是过时了么?SpringDataJpa又是什么?和Mybatis有什么区别?

一、前言 ps: 大三下学期&#xff0c;拿到了一份实习。进入公司后发现用到的技术栈有Spring Data Jpa\Hibernate,但对于持久层框架我只接触了Mybatis\Mybatis-Plus&#xff0c;所以就来学习一下Spring Data Jpa。 1.回顾MyBatis 来自官方文档的介绍&#xff1a;MyBatis 是一款…...

数学建模拓展内容:卡方检验和Fisher精确性检验(附有SPSS使用步骤)

卡方检验和Fisher精确性检验卡方拟合度检验卡方独立性检验卡方检验的前提假设Fisher精确性检验卡方拟合度检验 卡方拟合度检验概要&#xff1a;卡方拟合度检验也被称为单因素卡方检验&#xff0c;用于检验一个分类变量的预期频率和观察到的频率之间是否存在显著差异。 卡方拟…...

【Python学习笔记之七大数据类型】

Python数据类型&#xff1a;Number数字、Boolean布尔值、String字符串、list列表、tuple元组、set集合、dictionary字典 int整数 a1 print(a,type(a))float浮点数 b1.1 print(b,type(b))complex复数 c100.5j print(c,type(c))bool布尔值:True、False,true和false并非Python…...

Android系统之onFirstRef自动调用原理

前言&#xff1a;抽丝剥茧探究onFirstRef究竟为何在初始化sp<xxx>第一个调用&#xff1f;1.onFirstRef调用位置<1>.system/core/libutils/RefBase.cpp#include <utils/RefBase.h>//1.初始化强指针 void RefBase::incStrong(const void* id) const {weakref_i…...

ipv6上网配置

一般现在的宽带都已经支持ipv6了&#xff0c;但是需要一些配置才能真正用上ipv6。记录一下配置过程。 当前测试环境为移动宽带&#xff0c;光猫下面接了一个路由器&#xff0c;家里所有的设备都挂到这个路由器下面的。 1. 光猫改桥接 光猫在使用路由模式下&#xff0c;ipv6无…...

python实现聚类技术—复杂网络社团检测 附完整代码

实验内容 某跆拳道俱乐部数据由 34 个节点组成,由于管理上的分歧,俱乐部要分解成两个社团。 该实验的任务即:要求我们在给定的复杂网络上检测出两个社团。 分析与设计 实验思路分析如下: 聚类算法通常可以描述为用相似度来衡量两个数据的远近,搜索可能的划分方案,使得目标…...

如何判断两架飞机在汇聚飞行?(如何计算两架飞机的航向夹角?)内含程序源码

ok&#xff0c;在开始一切之前&#xff0c;让我先猜一猜&#xff0c;你是不是想百度“二维平面下如何计算两个移动物体的航向夹角&#xff1f;”如果是&#xff0c;那就请继续往下看。 首先&#xff0c;我们要明确一个概念&#xff1a;航向角≠航向夹角&#xff01;&#xff0…...

Scipy稀疏矩阵bsr_array

文章目录基本原理初始化内置方法基本原理 bsr&#xff0c;即Block Sparse Row&#xff0c;bsr_array即块稀疏行矩阵&#xff0c;顾名思义就是将稀疏矩阵分割成一个个非0的子块&#xff0c;然后对这些子块进行存储。通过输入维度&#xff0c;可以创建一个空的bsr数组&#xff0…...

LeetCode笔记:Weekly Contest 332

LeetCode笔记&#xff1a;Weekly Contest 332 1. 题目一 1. 解题思路2. 代码实现 2. 题目二 1. 解题思路2. 代码实现 3. 题目三 1. 解题思路2. 代码实现 4. 题目四 1. 解题思路2. 代码实现 比赛链接&#xff1a;https://leetcode.com/contest/weekly-contest-332/ 1. 题目一…...

autox.js在vscode(win7)与雷神模拟器上的开发环境配置

目录 下载autox.js 安装autox.js&#xff1f; 在电脑上搭建autox.js开发环境 安装vscode 安装autox.js插件 雷神模拟器连接vscode 设置雷神模拟器IP 设置autox.js应用IP地址等 下载autox.js 大体来说&#xff0c;就是一个运行在Android平台上的JavaScript 运行环境 和…...

创建阿里云物联网平台

创建阿里云物联网平台 对云平台设备创建过程做记录&#xff0c;懒得再看视频 文章参考视频&#xff1a;https://www.bilibili.com/video/BV1jP4y1E7TJ?p26&vd_source50694678ae937a743c59db6b5ff46c31 阿里云&#xff1a;https://www.aliyun.com 1&#xff0e;物联网平…...

【链式二叉树】数据结构链式二叉树的(万字详解)

前言&#xff1a; 在上一篇博客中&#xff0c;我们已经详解学习了堆的基本知识&#xff0c;今天带大家进入的是二叉树的另外一种存储方式----“链式二叉树”的学习&#xff0c;主要用到的就是“递归思想”&#xff01;&#xff01; 本文目录1.链式二叉树的实现1.1前置说明1.2结…...

Koa2篇-简单介绍及使用

一.简介koa2是基于 Node.js 平台的下一代 web 开发框架, 致力于成为一个更小、更富有表现力、更健壮的 Web 框架。 可以避免异步嵌套. express中间件是异步回调,Koa2原生支持async/await二.async/awaitconst { rejects } require("assert"); const { resolve } req…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...