断言与反射——以golang为例
断言
x.(T) 检查x的动态类型是否是T,其中x必须是接口值。
简单使用
func main() {var x interface{}x = 100value1, ok := x.(int)if ok {fmt.Println(value1)}value2, ok := x.(string)if ok {//未打印fmt.Println(value2)}
}
需要注意如果不接受第二个参数就是OK,这里失败的话则会直接panic,这里还存在一种情况就是x为nil同样会panic。
func main() {var x interface{}x = "Hello World"value := x.(int)fmt.Println(value)
}
panic: interface conversion: interface {} is string, not int
所以就有这种写法
switch写法
func JudgeType(a interface{}) {switch value := a.(type) {case nil:fmt.Println("Type is nil")case int:fmt.Println("int", value)case string:fmt.Println("string:", value)case A:fmt.Println("类型A:", value)case *A:fmt.Println("指针A", value)default:fmt.Println("未匹配")}
}
注意 断言好像是只能一层一层去处理的 不能一次直接
package mainimport ("encoding/json""fmt"
)func main() {json_str := `{"font_size": 0.4,"lang": "zh","version": "en-v1.2.0.4-t0.3.c","body": [{"content": "最近很多人问我这个概念"},{"content": "在过去的一年里我一直很喜欢"}]}`var json_map map[string]interface{}json.Unmarshal([]byte(json_str), &json_map)//这里直接一步到位 断言成[]map[string]interface {} 会报错 panic: interface conversion: interface {} is []interface {}, not []map[string]interface {}//同理[]map[string]string也不可以body := json_map["body"].([]interface{})for _, item := range body {itemMap := item.(map[string]interface{}) //map[string]string依然报错fmt.Println(itemMap["content"])}}
在这个例子中就是 我们每次只能断言一个级别 比如第一层断言是个切片[],第二层断言是个map[string]
以及注意 interface类型 都要加{}
但是 在处理json的时候
type body_struct []map[string]stringvar json_map map[string]body_structjson.Unmarshal([]byte(json_str), &json_map)
可以直接这样,猜测是json这个包内部进行了处理吧
反射
前置知识
用到了前面断言的知识
Go语言中的变量是分为两部分的:
• 类型信息:预先定义好的元信息。
• 值信息:程序运行过程中可动态变化的。
在 GoLang 的反射机制中,任何接口值都由是一个具体类型和具体类型的值两部分组成的。
golang变量包含两个属性 type和value,这是一个pair对。
type Reader interface {ReadBook( )
}
type Writer interface {WriteBook()
}
//一个具体的结构体
type Book struct {
}
//Book类实现了Reader接口
func(this *Book)ReadBook(){fmt.Println("Read a Book")
}
Book类实现了Writer 接口
func(this *Book)WriteBook(){fmt.Println("Write a Book")
}
func main(){//b:pair<type:Book,value:book{}地址>b := &Book{}//r: pair<type:, value:>var r Reader//r:pair<type:Book, value:book{}地址>r = br.ReadBook()var w writer//r: pair<type:Book,value:book{}地址>w=r.(Writer)//此处的断言为什么会成功?因为w与r 具体的type是一致
简单的理解就是 Book实现了两个接口,断言成功就是reader指向的book对象可以转为writer
是什么
反射是静态语言具有动态属性的体现
反射是指在程序运行期间对程序本身进行访问和修改的能力。正常情况程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身的信息。支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们
有时我们需要写一个函数,这个函数有能力统一处理各种值类型,而这些类型可能无法共享同一个接口,也可能布局未知,也有可能这个类型在我们设计函数时还不存在,这个时候我们就可以用到反射
反射的功能
-
反射可以在程序运行期间动态的获取变量的各种信息,比如变量的类型 类别
-
如果是结构体,通过反射还可以获取结构体本身的信息,比如结构体的字段、结构体的方法、结构体的 tag。
-
通过反射,可以修改变量的值,可以调用关联的方法
reflect包与基本用法
在 GoLang 中,反射的相关功能由内置的 reflect 包提供,任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value 两部分组成,并 且 reflect 包 提 供 了
- reflect.TypeOf
- reflect.ValueOf
两个重要函数来获取任意对象的 Value 和 Type
%T不也可以获取类型么?----可能%T就是通过反射来得到的
reflect.TypeOf()
使用 reflect.TypeOf()函数可以接受任意 interface{}参数,可以获得任意值的类型对象(reflect.Type),程序通过类型对象可以访问任意值的类型信息
在反射中关于类型还划分为两种:类型(Type)和种类(Kind)
因为在 Go 语言中我们可以使用 type 关键字构造很多自定义类型,而种类(Kind)就是指底层的类型,但在反射中,
当需要区分指针、结构体等大品种的类型时,就会用到种类(Kind)。 举个例子,我们定义了两个指针类型和两个结构体类型,通过反射查看它们的类型和种类。
Go 语言的反射中像数组、切片、Map、指针等类型的变量,它们的.Name()都是返回空
import ("fmt""reflect"
)func reflectFn(x interface{}) {// 反射获取任意变量类型v := reflect.TypeOf(x)name := v.Name() // 类型名称kind := v.Kind() // 种类(底层类型)fmt.Printf("类型是%v,类型名称是%v,种类是%v \n", v, name, kind)}// 自定义一个myInt类型
type myInt int// Person结构体
type Person struct {Name stringAge int
}func main() {a := 10b := "s"// 打印基本类型reflectFn(a) // 类型是int,类型名称是int,种类是intreflectFn(b) // 类型是string,类型名称是string,种类是string// 打印自定义类型和结构体类型var i myInt = 3var p = Person{"1",2,}reflectFn(i) // 类型是main.myInt,类型名称是myInt,种类是intreflectFn(p) // 类型是main.Person,类型名称是Person,种类是struct// 打印指针类型var f = 25reflectFn(&f) // 类型是*int,类型名称是,种类是ptr}
与前面x.(type)区别
a.(type)
是类型断言中的特殊语法,仅在 switch 语句中使用,用于通过接口变量获取其动态类型。例如:
switch v := a.(type) {
case int:fmt.Println("int:", v)
case string:fmt.Println("string:", v)
}
该语法直接通过接口值的动态类型进行分支判断46。
reflect.TypeOf(a)
是反射包中的函数,返回 reflect.Type 接口类型的对象,用于获取任意值的类型信息。例如:
typeOfA := reflect.TypeOf(a)
fmt.Println(typeOfA.Name(), typeOfA.Kind())
该函数通过反射机制解析值的类型,适用于动态类型检查12。
功能与灵活性
.(type)
仅能判断接口变量的动态类型,无法获取更详细的类型元信息(如结构体字段、方法等)。
需在代码中显式列出所有可能的类型分支,适用于类型已知或有限的场景
`reflect.TypeOf``返回完整的类型元信息,包括类型名称(Name)、种类(Kind)、结构体字段、方法等。
支持动态处理任意类型,适用于编写通用代码(如序列化、ORM 框架)或需要深度类型分析的场景
性能开销
a.(type)
类型断言是 Go 语言的内置语法,性能开销极低,几乎等同于普通的条件判断。
reflect.TypeOf
反射操作需要运行时动态解析类型信息,涉及额外的内存分配和间接调用,性能开销较高。应避免在性能敏感的场景中使用
reflect.ValueOf() 获取原始值
reflect.ValueOf()返回的是 reflect.Value 类型,其中包含了原始值的值信息。reflect.Value 与原始值之间可以互相转换
func reflectValue(x interface{}) {// 通过反射获取到值v := reflect.ValueOf(x)fmt.Printf("%v, %T \n", v, v) // 10, reflect.Value,获取到的类型是reflect.Valuefmt.Printf("%v,%T", v.Int(), v.Int()) // 10,int64,获取到原始值和类型,因为传入是数字,所以是v.Int()
}
func main() {var i = 10reflectValue(i)
func reflectValue(x interface{}) {v := reflect.ValueOf(x)kind := v.Kind() // 获取种类// 判断底层种类 switch kind {// 是int类型case reflect.Int64:fmt.Println(v.Int())case reflect.Float64:fmt.Println(v.Float())case reflect.String:fmt.Println(v.String())}
}
set通过反射设置变量的值
import ("fmt""reflect"
)func reflectValue(x interface{}) {v := reflect.ValueOf(x)// 如果传入的值是一个指针地址,那需要通过Elem().Kind()获取具体种类,Elem()返回 Type 对象所表示的指针指向的数据// 如果只是v.kind,获取的到的是指针类型kind := v.Elem().Kind() // int64if kind == reflect.Int64 {// int是SetInt string是SetString等v.Elem().SetInt(3)}
}func main() {var i = 10// 值类型修改副本不会影响原始值,所以需要通过指针地址reflectValue(&i)fmt.Println(i) // 3}
import (
“fmt”
“reflect”
)
// studen结构体
type Student struct {
Name string json:"name"
Age int json:"age"
Score int json:"score"
}
// 结构体方法 获取学生信息
func (s Student) GetInfo() string {
return fmt.Sprintf(“姓名%v 年龄%v 成绩%v”, s.Name, s.Age, s.Score)
}
// 结构体方法 修改学生信息
func (s *Student) SetInfo(name string, age, score int) {
s.Name = name
s.Age = age
s.Score = score
}
// 结构体方法 打印
func (s Student) PrintInfo() {
fmt.Println(“print info”)
}
func PrintStructField(s interface{}) {
// 获取类型对象
t := reflect.TypeOf(s)
/*
通过类型变量里面的Field获取结构体字段*/
// 通过类型变量.Field(下标)可以获取结构体的字段对象
field0 := t.Field(0)// 获取到结构体的Name字段对象
fmt.Println(field0) // {Name string json:"name" 0 [0] false}fmt.Printf("%#v \n", field0) // reflect.StructField{Name:"Name", PkgPath:"", Type:(*reflect.rtype)(0xe748c80), Tag:"json:\"name\"", Offset:0x0, Index:[]int{0}, Anonymous:false}
// 获取字段名称
fmt.Println(field0.Name) // Name
// 获取字段类型
fmt.Println(field0.Type) // string
// 获取字段tag - json类型
fmt.Println(field0.Tag.Get("json")) // name/*通过类型变量里面的FieldByName获取结构体字段
*/
// FieldByName返回两个值,一个是具体的值,一个是是否成功
field1, ok := t.FieldByName("Age")
if ok {fmt.Println(field1.Name) // 字段名称:Agefmt.Println(field1.Type) // 字段类型:intfmt.Println(field1.Tag.Get("json")) // 字段的json类型的tag :age
}/*通过类型变量的NumField获取该结构体有多少个字段
*/var count = t.NumField()
fmt.Println(count) // 3
}
func main() {
var student = Student{"小李", 15, 100}
PrintStructField(student)
}
通过值变量获取结构体值的值信息#
func PrintStructField(s interface{}) {
/*
通过值变量获取结构体属性对应的值
*/
v := reflect.ValueOf(s)
// 方式一
fmt.Println(v.FieldByName(“Name”)) // 小李
fmt.Println(v.FieldByName(“Age”)) // 15
// 方式二 可以通过循环获取所有的属性值
fmt.Println(v.Field(2)) // 100
}
通过反射修改结构体的属性值#
func ReflectSetValue(s interface{}) {
// 类型对象
t := reflect.TypeOf(s)
// 值对象
v := reflect.ValueOf(s)
// 判断传入的结构体是否是指针类型,因为非指针是值类型,不能修改值,必现使用指针类型
if t.Kind() != reflect.Ptr {
fmt.Println(“传入的不是指针类型”)
return
// 判断传入的指针是不是结构体指针
} else if t.Elem().Kind() != reflect.Struct {fmt.Println("传入的不是结构体指针")return
}
// 获取Name字段的指针值
name := v.Elem().FieldByName("Name")
// 修改属性值
name.SetString("小王")
}
func main() {
var student = Student{"小李", 15, 100}
// 如果传入一个值接收者,没有办法修改结构体的值,如果要修改对应值,需要传入指针接收者
ReflectSetValue(&student)
fmt.Println(student.Name) // 小王
}
通过类型变量获取结构体方法#
// 打印结构体方法
func PrintStructFn(s interface{}) {
t := reflect.TypeOf(s)
// 通过类型变量的Method(下标)获取结构体的方法
method0 := t.Method(0) // 下标取的方法和结构体的顺序没有关系,和结构体的ASCII码有关系
fmt.Println(method0.Name) // 下标为0的方法名:GetInfo
fmt.Println(method0.Type) // func(main.Student) string// 通过MethodByName 获取结构体方法
// 该方法两个返回值,一个是方法名,一个是是否有该方法的状态
method1, ok := t.MethodByName("PrintInfo")
if ok {fmt.Println(method1.Name) // PrintInfofmt.Println(method1.Type) // func(main.Student)}
// 获取结构体一共有几个方法
fmt.Println(t.NumMethod()) // 2 Student结构体定义了3个方法,有两个接收者类型是结构体,有一个接收者类型是指针接收者,如果s接收的是值接收者,只能统计值接收者的方法数量,如果是指针接收者,可以统计所有的方法的数量
}
func main() {
var student = Student{"小李", 15, 100}
PrintStructFn(student)
}
通过值变量执行结构体方法#
func RunStructFn(s interface{}) {
v := reflect.ValueOf(s)
// 方法一 通过下标执行对应的方法,Call传递对应参数,nil代表没有参数
v.Method(1).Call(nil) // print info
// 方法二 通过MethodByName执行对应方法,返回值是一个切片
// 传入参数调用,Call方法传入的参数需要是一个reflect.Value类型的切片
var params []reflect.Value
params = append(params, reflect.ValueOf("小李"))
params = append(params, reflect.ValueOf(20))
params = append(params, reflect.ValueOf(95))
v.MethodByName("SetInfo").Call(params)fmt.Println(v.MethodByName("GetInfo").Call(nil)) // [姓名小李 年龄20 成绩95]
}
func main() {
var student = Student{"小李", 15, 100}
// 如果传入一个值接收者,没有办法修改结构体的值,如果要修改对应值,需要传入指针接收者
RunStructFn(&student)
}
应用场景
(1)动态类型检查
反射可以用于在运行时检查变量的类型,这在处理未知类型的数据时非常有用。例如,编写通用函数或库时,可能需要根据传入参数的类型执行不同的操作。
func checkType(data interface{}) {t := reflect.TypeOf(data)fmt.Println("Type:", t)
}
(2)动态调用方法
反射可以用于在运行时动态调用对象的方法,这在需要根据条件调用不同方法时非常有用
type MyStruct struct{}func (m *MyStruct) MyMethod() {fmt.Println("MyMethod called")
}func callMethod(obj interface{}, methodName string) {v := reflect.ValueOf(obj)method := v.MethodByName(methodName)if method.IsValid() {method.Call(nil)}
}
(3)结构体字段操作比如处理配置文件
反射可以用于在运行时动态访问和修改结构体的字段,这在处理配置文件、数据库映射等场景时非常有用。
type Person struct {Name stringAge int
}func setField(obj interface{}, fieldName string, value interface{}) {v := reflect.ValueOf(obj).Elem()field := v.FieldByName(fieldName)if field.IsValid() && field.CanSet() {field.Set(reflect.ValueOf(value))}
}
动态绑定配置字段
通过反射动态解析配置文件(如 YAML、JSON),将键值对自动映射到预定义结构体的字段中,无需手动逐字段赋值。
典型实现:
读取配置文件内容后,遍历结构体的反射元数据,匹配键名与字段名(支持大小写转换、json/yaml 标签解析)。
处理嵌套结构体时,递归遍历子结构体字段,实现复杂配置的自动加载8。
支持热加载配置
因为已经变成二进制文件了 配置新消息变成了一个内存中的结构体 所以我们要用反射才能找到它?或者 因为外部是不确定的 你不知道传进来的配置文件是啥样的
通过反射动态更新配置对象,实现运行时重载配置文件(如 SIGHUP 信号触发)而不重启服务。
实现逻辑:
- 监听配置文件变化,重新读取文件内容并生成新配置对象。
- 通过反射对比新旧配置对象差异,仅更新发生变化的字段值(避免全局替换导致状态不一致)
统一配置处理接口
编写通用配置解析函数,支持多种格式(JSON/YAML/TOML)的自动适配。
代码示例:
func LoadConfig(filePath string, config interface{}) error {data, _ := os.ReadFile(filePath) // 读取文件val := reflect.ValueOf(config).Elem()// 根据文件后缀选择解析逻辑(如解析为 map[string]interface{})parsedData := parseByFileType(filePath, data) // 反射遍历结构体字段并赋值for key, value := range parsedData {field := val.FieldByName(strings.Title(key)) if field.IsValid() && field.CanSet() {field.Set(reflect.ValueOf(value).Convert(field.Type())) }}return nil
}
// 调用示例:LoadConfig("config.yaml", &ServerConfig{})
说明:通过反射的 FieldByName 和 Set 方法实现键值动态映射,支持类型转换(如字符串转 int)。
处理环境变量与默认值
结合反射实现配置优先级逻辑(如环境变量 > 配置文件 > 默认值)。
实现方式:
-遍历结构体字段,检查是否存在 env 标签(如 env:“PORT”),优先从环境变量读取值。
若未配置环境变量或文件字段,通过反射检查并设置字段的默认值(如 default:“8080” 标签)。
动态校验配置合法性
利用反射实现字段类型校验或自定义规则检查(如端口号范围、必填字段)。
示例逻辑:
func ValidateConfig(config interface{}) error {t := reflect.TypeOf(config).Elem()v := reflect.ValueOf(config).Elem()for i := 0; i < t.NumField(); i++ {field := t.Field(i)value := v.Field(i)// 检查必填标签(如 `required:"true"`)if field.Tag.Get("required") == "true" && value.IsZero() {return fmt.Errorf("字段 %s 必填", field.Name)}}return nil
}
用途:防止因配置缺失或格式错误导致服务启动失败58。
注意事项
性能开销:反射操作比静态代码慢,建议在初始化阶段或低频热加载场景使用,避免高频调用
(4)序列化与反序列化
反射可以用于实现通用的序列化和反序列化功能,例如将结构体转换为JSON或从JSON解析为结构体
func toJSON(obj interface{}) string {v := reflect.ValueOf(obj)t := reflect.TypeOf(obj)var result stringfor i := 0; i < v.NumField(); i++ {field := t.Field(i)value := v.Field(i)result += fmt.Sprintf("%s: %v\n", field.Name, value.Interface())}return result
}
(5)插件系统
反射可以用于实现插件系统,动态加载和调用插件中的函数或方法。
func loadPlugin(pluginPath string, functionName string) {p, err := plugin.Open(pluginPath)if err != nil {log.Fatal(err)}f, err := p.Lookup(functionName)if err != nil {log.Fatal(err)}f.(func())()
}
(6)依赖注入
反射可以用于实现依赖注入框架,动态地将依赖注入到对象中。
type Service struct {Dependency *Dependency
}func injectDependency(service interface{}, dependency interface{}) {v := reflect.ValueOf(service).Elem()field := v.FieldByName("Dependency")if field.IsValid() && field.CanSet() {field.Set(reflect.ValueOf(dependency))}
相关文章:
断言与反射——以golang为例
断言 x.(T) 检查x的动态类型是否是T,其中x必须是接口值。 简单使用 func main() {var x interface{}x 100value1, ok : x.(int)if ok {fmt.Println(value1)}value2, ok : x.(string)if ok {//未打印fmt.Println(value2)} }需要注意如果不接受第二个参数就是OK,这…...
react函数组件中,className字符串、style对象如何在父子组件之间传递
一、需要传递的样式在父组件的scss文件中提前写好 子组件的dom解析后: 二、向子组件直接传递style对象...
WHAT - React Portal 机制:将子组件渲染到 DOM 的指定节点
文章目录 适合场景基本语法示例:Modal 弹窗1. 创建一个简单的 Modal.tsx2. 在 App 中使用 为什么要用 Portal?TypeScript 中 Portal 类型定义? 适合场景 React Portal 是 React 提供的一种机制,让你可以将子组件渲染到 DOM 的指定…...
企业绿电消纳比例不达标?安科瑞微电网智慧能源平台助力企业低碳转型
方案配置支持请联系安科瑞电气周女士 企业绿电消纳政策是国家推动能源转型和实现“双碳”目标的重要抓手,近年来政策体系逐步完善。企业通过建设“源网荷储”一体化项目、虚拟电厂等技术,提升绿电消纳能力。 一、安科瑞提供解决方案 深耕用电业务&…...
uni-app初学
文章目录 1. pages.json 页面路由2. 图标3. 全局 CSS4. 首页4.1 整体框架4.2 完整代码4.3 轮播图 swiper4.3.1 image 4.4 公告4.4.1 uni-icons 4.5 分类 uni-row、uni-col4.6 商品列表 小程序开发网址: 注册小程序账号 微信开发者工具下载 uniapp 官网 HbuilderX 下…...
网络划分vlan隔离
隔离划分 比如我们想要将pc1和pc2隔离,我们只需在lsw1交换机中,如下配置: sys 先进入系统视图 先后输入 代表创建2个隔离区 vlan 10 vlan 20 然后进入0/0/1、0/0/2设置隔离类型,并划分隔离区域 int gi0/0/01 port l…...
HDCP(四)
HDCP驱动开发实战深度解析 以下从协议栈架构、核心模块实现、安全设计到硬件集成,结合HDCP 2.x规范与主流硬件平台(如ARM、FPGA)特性,系统拆解驱动开发关键环节: 1. 协议栈架构与模块划分 驱动分层设计 硬件抽象层&…...
大数据(7.4)Kafka存算分离架构深度实践:解锁对象存储的无限潜能
目录 一、传统架构的存储困境与破局1.1 数据爆炸时代的存储挑战1.2 存算分离的核心价值矩阵 二、对象存储集成架构设计2.1 分层存储核心组件2.2 关键配置参数优化 三、深度集成实践方案3.1 冷热数据分层策略3.1.1 存储策略性能对比 3.2 跨云数据湖方案 四、企业级应用案例4.1 金…...
SLAM文献之SuMa++: Efficient LiDAR-based Semantic SLAM
SuMa是基于Surfel的SLAM算法SuMa的改进版本,通过引入语义分割信息提升动态环境下的鲁棒性和回环检测性能。以下从算法原理和公式推导两方面详细阐述: 一、SuMa算法原理 1. 基础:SuMa算法 SuMa使用Surfel(表面元素)构…...
react中通过 EventEmitter 在组件间传递状态
要在 Reply 组件中通过 statusChangeEvent 发送状态值,并在 Select 组件中接收这个状态值 status,你可以按照以下步骤实现: //Event.jsimport EventEmitter from events;export const statusChangeEvent new EventEmitter();// 工单状态切换…...
机器学习 从入门到精通 day_03
1. KNN算法-分类 1.1 样本距离判断 明可夫斯基距离:欧式距离,明可夫斯基距离的特殊情况;曼哈顿距离,明可夫斯基距离的特殊情况。 两个样本的距离公式可以通过如下公式进行计算,又称为欧式距离。 (…...
WHAT - React 两个重要的 Typescript 类型:ReactNode vs JSX.Element
文章目录 ReactNode 是什么?示例用途 JSX.Element 是什么?示例用途 ReactNode vs JSX.Element 对比使用建议其他相关类型例子总结 这两个类型 ReactNode 和 JSX.Element 在 React TypeScript 中经常出现,但它们含义不同,适用场景…...
了解 DeFi:去中心化金融的入门指南与未来展望
去中心化金融,或 DeFi,代表着全球金融体系运作方式的革命性转变。它是一个总称,指的是一个不断增长的去中心化应用程序(dapp)、协议和平台生态系统,这些生态系统构建在公共区块链网络上,无需传统…...
四旋翼无人机手动模式
无人机的手动模式(Manual Mode)是指飞手完全通过遥控器手动控制无人机的飞行姿态、高度、方向和速度,无需依赖自动稳定系统或辅助功能(如GPS定位、气压计定高、视觉避障等)。这种模式赋予操作者最大的操控自由度&a…...
航电系统之驱动系统篇
航电系统的驱动系统是航空电子系统中负责为各类电子设备、传感器、执行机构及控制模块提供稳定、可靠电能的关键部分。其核心功能在于将飞机电源系统的电能转换为适合航电设备使用的形式,确保航电系统在各种飞行条件下正常运行。以下从组成结构、工作原理、技术特点…...
《嵌入式开发实战:基于Linux串口的LED屏显系统设计与实现》
一、项目概述 本文介绍如何通过Linux系统的串口通信,驱动工业级LED显示屏实现动态数据展示。项目采用C语言开发,包含气象数据显示和实时时钟两大核心功能,涉及以下关键技术点: 串口通信协议配置 自定义数据帧封装 CRC16校验算法…...
记录一下移动端uView动态表单校验
uni-app开发uView必不可少,uView是uni-app生态专用的UI框架。 像element-ui一样uView也有自己的表单组件u-form。 对于下图这种列表数据该如何做表单校验,官方文档好像没有具体的案例,记录一下。 问题: 主要实现步骤:…...
Django项目入门二
Django项目入门二 目录 1.修改部门数据 2.新增员工数据 3.修改员工数据 4.删除员工数据 一、修改部门数据 上一篇文章, 我们只剩下修改功能没有做了, 那在这篇文章, 我们给它补上。 在做之前, 我们需要对views.py文件进行调整, 由于我们考虑到有部门信息和员工信息, 如…...
Java创建Android自用证书
在 Android 开发中,如果需要创建一个自用的证书,可以使用 Java 开发工具包(JDK)自带的 keytool 工具。 KeystoreGenerator.java import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.…...
Redis——实现消息队列
目录 前言 基于List结构模拟消息队列 基于List实现消息队列优缺点 基于PubSub(订阅者)实现消息队列 示例 基于PubSub的消息队列的优缺点 基于Stream的消息队列 STREAM类型消息队列的XREAD命令特点: 基于Stream的消息队列-消费者组 基于…...
学习51单片机Day01---做实验前置一些内容
目录 一、前面要看的: 1.下载软件 2.如何开始做? 3.基本框架: 4.如何编译运行: 5.可以运行的样子: 6.怎么生成hex: 7.滴滴放到单片机上: 二、过程中可能出现的问题(一直会更…...
pipe匿名管道实操(Linux)
管道相关函数 1 pipe 是 Unix/Linux 系统中的一个系统调用,用于创建一个匿名管道 #include <unistd.h> int pipe(int pipefd[2]); 参数说明: pipefd[2]:一个包含两个整数的数组,用于存储管道的文件描述符: pi…...
vscode 异常关闭后无法远程连接服务器
笔记本没关机只是合上,结果第二天上班整台笔记本高度发热发烧,吓坏了。。。 强制关机后再开机,幸好能用。但是vscode连接服务器一直不对。 解决方式: 解决一:打开VS Code菜单"View"->“Command Palatt…...
Rust主流框架性能比拼: Actix vs Axum vs Rocket
本内容是对知名性能评测博主 Anton Putra Actix (Rust) vs Axum (Rust) vs Rocket (Rust): Performance Benchmark in Kubernetes 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在以下中,我们将比较 Rust 生态中最受欢迎的几个框架。我会将三个应用程序…...
二氧化铪(HfO2)市场发展分析:从基础到前沿应用
引言:探索二氧化铪的重要性与市场潜力 在现代材料科学中,二氧化铪(HfO2)作为一种关键的高介电常数(High-k)材料,正逐渐成为半导体行业不可或缺的一部分。二氧化铪是一种白色的固体,…...
写一个简单的demo来理解数据库外键
准备工作 安装MySQL 确保已安装MySQL,并启动服务。可以通过命令行或工具(如MySQL Workbench)操作。 创建数据库 sql 复制 CREATE DATABASE school; USE school;创建父表和子表 步骤 1:创建父表(students)…...
Prompt-to-prompt image editing with cross attention control
Project Page: https://prompt-to-prompt.github.io Paper: https://arxiv.org/abs/2208.01626 Code: https://github.com/google/prompt-to-prompt 文章目录 1. Introduction2. Method2.1 Cross-attention in text-conditioned Diffusion Models2.2 Controlling the Cross-att…...
C++Cherno 学习笔记day18 [71]-[75] C++安全、PCH、dynamic_cast、基准测试、结构化绑定
b站Cherno的课[71]-[75] 一、现代C中的安全以及如何教授二、C的预编译头文件PCH三、C的dynamic_cast四、C的基准测试五、C的结构化绑定 一、现代C中的安全以及如何教授 安全编程,或者说C编程中,降低崩溃,内存泄露、非法访问等问题 C11&#…...
根据 PID 找到对应的 Docker 容器
引言 在日常运维与调试过程中,我们常常需要查找某个进程所属的 Docker 容器。当系统出现问题或资源异常时,根据进程的 PID 找到其所属容器可以帮助我们迅速定位问题。本文将介绍如何利用 Linux 的 cgroup 机制,以及 Docker 提供的工具来完成…...
传统项目纯前端实现导出excel之xlsx.bundle.js
传统项目纯前端实现导出excel之xlsx.js 自从vue问世后,使得前端开发更加简洁从容,极大的丰富组件样式和页面渲染效果,使得前端功能的可扩展性得到极大地加强。虽然vue的使用对于前后端分离的项目对于功能实现与扩展有了质的飞跃,但…...
大型手游 DDoS 攻击怎么防护?游戏盾 SDK 技术解剖实录
一、重灾区警报:大型手游为何成为 DDoS 靶心? 1. 血淋淋的行业数据 攻击规模暴涨:2024 年全球手游遭受 > 300Gbps 攻击次数同比激增 173%(Akamai 报告)经济杀伤链:1 小时 500Gbps 攻击可造成ÿ…...
【Harmony】状态管理(V1)
一、概述 文章目录 一、概述二、组件状态管理1、State1.1、State简介1.2、State简单示例 2、Prop2.1、Prop简介2.2、Prop底层实现原理2.3、Prop简单示例 3、Link3.1、Link简介3.2、Link底层实现原理3.3、Link简单示例 4、Provide Consume4.1、Provide Consume简介4.2、Provide …...
udev规则实例:监听usb插拔事件并做出相应
在 Linux 和 Android 系统中,USB 插拔事件的判断涉及从内核到用户空间的多层协作。以下是源码中关键判断点的梳理: 事件流程 内核层:UEvent 机制 USB 插拔事件首先由内核通过 UEvent 机制 上报。内核中的 USB 驱动(如 drivers/…...
【算法】【蓝桥23国A软件C】四版代码思路分析与逐步优化
题目来源:第十四届蓝桥杯大赛软件赛国赛C/C 大学 A 组 题目描述: 问题描述 给定一个 WH 的长方形,两边长度均为整数。小蓝想把它切割为很多个边长为整数的小正方形。假设切割没有任何损耗,正方形的边长至少为 2,不允…...
程序设计竞赛1
题目1 2025年春节期间,DeepSeek作为“AI界的天降紫微星”成为新晋效率神器,热度席卷全球,其团队主创成员也迅速引起了大家的关注。 DeepSeek之所以能在短时间内取得如此不凡成绩,与其团队成员的背景密不可分。团队汇聚了来自清华…...
android studio 2022打开了v1 签名但是生成的apk没有v1签名问题
我使用了Android Studio Flamingo | 2022.2.1 Patch 2版本的IDE编译了一个apk,但是apksigner查看apk的签名信息时,发现只有v2签名,没有v1签名。 apksigner verify -v app-debug.apk Verifies Verified using v1 scheme (JAR signing): false Verified usin…...
EPGAN:融合高效注意力的生成对抗网络图像修复算法
简介 简介:利用掩码设计来遮掉输入图像的一部分,将这类图像输入给生成器。生成器结合ECA注意力机制架构,利用感知损失、对抗损失和均方误差损失的加权和来作为生成器的损失计算。鉴别器分别对应掩码和整张图做损失计算。 论文题目:融合高效注意力的生成对抗网络图像修复算…...
使用模板报错:_G.unicode.len(orgline.text_stripped:gsub(“ “,““))
使用aegisub制作歌词特效,白嫖大佬的自动化模板时,经常会遇到如下报错: Runtime error in template code: Expected 1 arguments, got 2 Code producing error: ci {0,0}; cn _G.unicode.len(orgline.text_stripped:gsub(" ",&q…...
linux入门六:Linux Shell 编程
一、Shell 概述 1. 什么是 Shell? Shell 是 Linux 系统中用户与内核之间的桥梁,作为 命令解析器,它负责将用户输入的文本命令转换为计算机可执行的机器指令。 本质:Shell 是一个程序(如常见的 Bash、Zsh)…...
Franka 机器人x Dexterity Gen引领遥操作精细任务新时代
教授机器人工具灵活操作难题 在教授机器人灵活使用工具方面,目前主要有两种策略:一是人类遥控(用于模仿学习),二是模拟到现实的强化学习。然而,这两种方法均存在明显的局限性。 1、人类遥控(用…...
网络通讯协议UDP转发TCP工具_UdpToTcpRelay_双向版
UDP/TCP网络转发器程序说明书 1. 程序概述 本程序是一个高性能网络数据转发工具,支持UDP和TCP协议之间的双向数据转发,并具备以下核心功能: 协议转换:实现UDP↔TCP协议转换数据转换:支持十六进制/ASCII格式的数据转…...
深入理解 RxSwift 中的 Driver:用法与实践
目录 前言 一、什么是Driver 1.不会发出错误 2.主线程保证 3.可重放 4.易于绑定 二、Driver vs Observable 三、使用场景 1.绑定数据到UI控件 2.响应用户交互 3.需要线程安全的逻辑 4.如何使用Driver? 1.绑定文本输入到Label 2.处理按钮点击事件 3…...
【XML基础-3】深入理解XML Schema:XML的强大语义约束机制
XML(可扩展标记语言)作为数据交换的标准格式,在当今信息技术领域扮演着重要角色。然而,仅有基本的XML语法规则往往不足以满足复杂的数据验证需求。这正是XML Schema发挥作用的地方——它为XML文档提供了强大的语义约束能力。本文将…...
神经网络语言模型与统计语言模型的比较
神经网络语言模型(Neural Language Models, NLMs)与统计语言模型(Statistical Language Models, SLMs)是自然语言处理(NLP)中两类核心的语言建模方法,其核心差异体现在建模方式、表示能力、数据…...
大模型论文:CRAMMING TRAINING A LANGUAGE MODEL ON ASINGLE GPU IN ONE DAY(效率提升)-final
大模型论文:CRAMMING: TRAINING A LANGUAGE MODEL ON ASINGLE GPU IN ONE DAY(效率提升) 文章地址:https://arxiv.org/abs/2212.14034 摘要 近年来,语言建模的研究趋势集中在通过大规模扩展来提升性能,导致训练语言模型的成本变…...
构建AI应用(持续更新)
常用的框架: dify、coze:低代码模块化编程 langchain:面向程序人员 常规的应用: 语音转文字ASR,文字转语音TTS,下一步问题建议, 旅游计划,买点提取,情感陪聊&#x…...
【JAVA】JVM 堆内存“缓冲空间”的压缩机制及调整方法
1. 缓冲空间是否可压缩? 是的,JVM 会在满足条件时自动收缩堆内存,将未使用的缓冲空间释放回操作系统。但需满足以下条件: GC 触发堆收缩:某些垃圾回收器(如 G1、Serial、Parallel)在 Full GC …...
NLP高频面试题(三十八)——什么是LLM的灾难性遗忘?如何避免灾难性遗忘?
近年来,大语言模型在人工智能领域取得了显著进展。然而,随着模型的不断更新和新任务的引入,出现了一个重要的问题,即灾难性遗忘(Catastrophic Forgetting)。灾难性遗忘指的是大模型在连续学习新知识或新任务时,先前掌握的旧知识会迅速被覆盖或遗忘,从而导致模型在旧任务…...
Keepalived+LVS高可用集群实战:从原理到落地
在分布式系统架构中,服务的高可用性和负载均衡是保障业务连续性的核心要素。本文通过一次实验,深入探索了基于KeepalivedLVS的高可用负载均衡集群方案,带您从零开始理解原理、动手实践配置,并验证其可靠性。 一、实验目标 本次实…...
【JVM】JVM调优实战
😀大家好,我是白晨,一个不是很能熬夜😫,但是也想日更的人✈。如果喜欢这篇文章,点个赞👍,关注一下👀白晨吧!你的支持就是我最大的动力!Ǵ…...