当前位置: 首页 > 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…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...