golang 基础 泛型编程

news2024/11/14 17:58:05

(一) 示例1

package _case

import "fmt"

// 定义用户类型的结构体
type user struct {
	ID   int64
	Name string
	Age  uint8
}

// 定义地址类型的结构体
type address struct {
	ID       int
	Province string
	City     string
}

// 集合转列表函数,接受一个 map,返回一个切片
func mapToList[k comparable, T any](mp map[k]T) []T {
	// 创建切片,长度与 map 的长度相同
	list := make([]T, len(mp))
	var i int
	for _, data := range mp {
		list[i] = data
		i++
	}
	return list
}

// 打印通道内容的函数,接受一个通道并打印通道中的每一个数据
func myPrintln[T any](ch chan T) {
	for data := range ch {
		fmt.Println(data)
	}
}

// 主函数,执行类型转换和打印
func TTypeCase() {
	// 创建一个用户类型的 map
	userMp := make(map[int64]user, 0)
	// 向 map 中添加用户数据
	userMp[1] = user{ID: 1, Name: "heheda", Age: 18}
	userMp[2] = user{ID: 2, Name: "Jerry", Age: 20}
	userMp[3] = user{ID: 3, Name: "Tom", Age: 22}
	// 将用户 map 转换为用户列表
	userList := mapToList[int64, user](userMp)

	// 创建用户类型的通道,并启动 goroutine 打印通道数据
	ch := make(chan user)
	go myPrintln(ch)
	// 将用户列表中的数据发送到通道
	for _, u := range userList {
		ch <- u
	}
	close(ch)

	// 创建一个地址类型的 map
	addrMp := make(map[int64]address, 0)
	// 向 map 中添加地址数据
	addrMp[1] = address{ID: 1, Province: "湖南", City: "长沙"}
	addrMp[2] = address{ID: 2, Province: "广东", City: "揭阳"}
	// 将地址 map 转换为地址列表
	addrList := mapToList[int64, address](addrMp)

	// 创建地址类型的通道,并启动 goroutine 打印通道数据
	ch1 := make(chan address)
	go myPrintln(ch1)
	// 将地址列表中的数据发送到通道
	for _, addr := range addrList {
		ch1 <- addr
	}
	close(ch1)
}

// 泛型切片的定义
type List[T any] []T

// 泛型 map 的定义
// 声明两个泛型,分别为 k 、 v
type MapT[k comparable, v any] map[k]v

// 泛型通道的定义
type Chan[T any] chan T

func TTypeCase1() {
	// map[int64]user -> MapT[int64, user]
	userMp := make(MapT[int64, user], 0)
	userMp[1] = user{ID: 1, Name: "heheda", Age: 18}
	userMp[2] = user{ID: 2, Name: "Jerry", Age: 20}
	userMp[3] = user{ID: 3, Name: "Tom", Age: 22}

	var userList List[user]
	userList = mapToList[int64, user](userMp)

	ch := make(Chan[user])
	go myPrintln(ch)
	for _, u := range userList {
		ch <- u
	}
	close(ch)

	// map[int64]address -> MapT[int64, address]
	addrMp := make(MapT[int64, address], 0)
	addrMp[1] = address{ID: 1, Province: "湖南", City: "长沙"}
	addrMp[2] = address{ID: 2, Province: "广东", City: "揭阳"}

	var addrList List[address]
	addrList = mapToList[int64, address](addrMp)

	ch1 := make(Chan[address])
	go myPrintln(ch1)
	for _, addr := range addrList {
		ch1 <- addr
	}
	close(ch1)
}

这段代码展示了如何使用 Go 语言中的泛型、结构体和通道进行数据处理和打印。以下是对代码各部分的解释:

1.包和导入

package _case

import "fmt"
  • 导入 fmt 包用于格式化输入输出

 2.结构体定义

  • user 结构体 有三个字段:ID(类型 int64)、Name(类型 string)和 Age(类型 uint8)
  • address 结构体 有三个字段:ID(类型 int)、Province(类型 string)和 City(类型 string)

 3.泛型函数

func mapToList[k comparable, T any](mp map[k]T) []T {
    list := make([]T, len(mp))
    var i int
    for _, data := range mp {
        list[i] = data
        i++
    }
    return list
}
  • mapToList 是一个泛型函数,它接受一个 map 类型的参数 mp,并将其转换为切片(列表)
  • 这里使用了两个泛型类型参数:k(可比较类型)和 T(任意类型)

4.打印通道内容的泛型函数

func myPrintln[T any](ch chan T) {
    for data := range ch {
        fmt.Println(data)
    }
}
  • myPrintln 是一个泛型函数,接受一个通道类型的参数 ch,并打印通道中的每一个数据

5.主函数 TTypeCase

func TTypeCase() {
    userMp := make(map[int64]user, 0)
    userMp[1] = user{ID: 1, Name: "heheda", Age: 18}
    userMp[2] = user{ID: 2, Name: "Jerry", Age: 20}
    userMp[3] = user{ID: 3, Name: "Tom", Age: 22}
    userList := mapToList[int64, user](userMp)
    
    ch := make(chan user)
    go myPrintln(ch)
    for _, u := range userList {
        ch <- u
    }
    close(ch)
    
    addrMp := make(map[int64]address, 0)
    addrMp[1] = address{ID: 1, Province: "湖南", City: "长沙"}
    addrMp[2] = address{ID: 2, Province: "广东", City: "揭阳"}
    addrList := mapToList[int64, address](addrMp)
    
    ch1 := make(chan address)
    go myPrintln(ch1)
    for _, addr := range addrList {
        ch1 <- addr
    }
    close(ch1)
}
  • 这个函数首先创建两个 map 分别存储用户和地址数据
  • 使用 mapToList 将 map 转换为列表(切片)
  • 创建通道并启动 goroutine 打印通道数据
  • 将列表中的数据写入通道并关闭通道

 6.型类型

  • 定义三个新的泛型类型:ListMapT 和 Chan
type List[T any] []T
type MapT[k comparable, v any] map[k]v
type Chan[T any] chan T

7.另一主函数 TTypeCase1

func TTypeCase1() {
    // map[int64]user -> MapT[int64, user]
    userMp := make(MapT[int64, user], 0)
    userMp[1] = user{ID: 1, Name: "heheda", Age: 18}
    userMp[2] = user{ID: 2, Name: "Jerry", Age: 20}
    userMp[3] = user{ID: 3, Name: "Tom", Age: 22}
    
    var userList List[user]
    userList = mapToList[int64, user](userMp)
    
    ch := make(Chan[user])
    go myPrintln(ch)
    for _, u := range userList {
        ch <- u
    }
    close(ch)
    
    // map[int64]address -> MapT[int64, address]
    addrMp := make(MapT[int64, address], 0)
    addrMp[1] = address{ID: 1, Province: "湖南", City: "长沙"}
    addrMp[2] = address{ID: 2, Province: "广东", City: "揭阳"}
    
    var addrList List[address]
    addrList = mapToList[int64, address](addrMp)
    
    ch1 := make(Chan[address])
    go myPrintln(ch1)
    for _, addr := range addrList {
        ch1 <- addr
    }
    close(ch1)
}
  • TTypeCase1 函数与 TTypeCase 类似,但使用了自定义的泛型类型 MapT 和 List

相关知识点

  • 泛型 泛型允许函数和数据结构定义中使用类型参数,从而提升代码的复用性
  • 结构体 结构体是 Go 中用于将多个字段组合成一个单一类型的数据结构
  • 通道(Channel)通道是在 goroutine 之间传递数据的管道,可以同步或者异步
  • goroutine goroutine 是 Go 中轻量级的线程,用于并发编程
  • map map 是一种内建的数据结构,用于存储键值对

可以尝试运行和修改代码,进一步理解这些概念。

(二) 示例2

package _case

import "fmt"

// 定义接口 ToString,有一个 String() 方法
type ToString interface {
	String() string
}

// user 结构体实现 ToString 接口
func (u user) String() string {
	return fmt.Sprintf("ID: %d,Name: %s,Age: %d", u.ID, u.Name, u.Age)
}

// address 结构体实现 ToString 接口
func (addr address) String() string {
	return fmt.Sprintf("ID: %d,Province: %s,City: %s", addr.ID, addr.Province, addr.City)
}

// 定义泛型接口 GetKey,要求实现 Get() 方法返回类型 T
type GetKey[T comparable] interface {
	any
	Get() T
}

// user 结构体实现 GetKey 接口,Get() 返回 ID
func (u user) Get() int64 {
	return u.ID
}

// address 结构体实现 GetKey 接口,Get() 返回 ID
func (addr address) Get() int {
	return addr.ID
}

// 泛型函数 listToMap,将列表转换为 map
func listToMap[k comparable, T GetKey[k]](list []T) map[k]T {
	mp := make(map[k]T, len(list)) // 创建 map,长度为列表长度
	for _, data := range list {
		mp[data.Get()] = data // 使用 Get() 方法获取键
	}
	return mp
}

// 主函数,演示列表转 map 的操作
func InterfaceCase() {
	// 创建 user 列表,元素实现了 GetKey[int64] 接口
	userList := []GetKey[int64]{
		user{ID: 1, Name: "张三", Age: 18},
		user{ID: 2, Name: "李四", Age: 19},
	}
	// 创建 address 列表,元素实现了 GetKey[int] 接口
	addrList := []GetKey[int]{
		address{ID: 1, Province: "广东", City: "揭阳"},
		address{ID: 2, Province: "湖南", City: "长沙"},
	}
	// 将 user 列表转换为 map,并打印结果
	userMp := listToMap[int64, GetKey[int64]](userList)
	fmt.Println(userMp)
	// 将 address 列表转换为 map,并打印结果
	addrMp := listToMap[int, GetKey[int]](addrList)
	fmt.Println(addrMp)
}

 1.包和导入

package _case

import "fmt"

 导入 fmt 包用于格式化输入输出。

2.定义基本接口

type ToString interface {
    String() string
}

3.实现 ToString 接口

func (u user) String() string {
    return fmt.Sprintf("ID: %d,Name: %s,Age: %d", u.ID, u.Name, u.Age)
}

func (addr address) String() string {
    return fmt.Sprintf("ID: %d,Province: %s,City: %s", addr.ID, addr.Province, addr.City)
}
  • user 和 address 结构体实现了 ToString 接口的 String 方法,返回结构体的字符串表示。

 4.定义泛型接口

type GetKey[T comparable] interface {
    any
    Get() T
}

这是一个泛型接口声明。具体来说,GetKey 接口接受一个类型参数 T,这个类型参数必须是一个可比较的类型 (comparable)

(1)定义泛型接口

type GetKey[T comparable] interface {
  • GetKey 定义了一个泛型接口。
  • T 是一个类型参数,它必须是一个可比较的类型 (comparable)。可比较类型表示可以使用 == 和 != 运算符进行比较,常见的可比较类型包括整数、浮点数、字符串以及指针等。

(2)嵌入 any 接口

  • Go 1.18 引入了类型集合 any,它是 interface{} 的别名,表示任意类型
  • 在接口中嵌入 any 意味着该接口可以接受任何类型的实现

(3)定义方法

Get() T
  • 定义了一个方法 Get,这个方法返回类型 T
  • 因为 T 是一个类型参数,所以 Get 方法的返回值类型是泛型的,可以是任意 T 类型

5.实现 GetKey 接口

func (u user) Get() int64 {
    return u.ID
}

func (addr address) Get() int {
    return addr.ID
}
  • user 和 address 结构体实现了 GetKey 接口的 Get 方法,分别返回结构体的 ID 字段
  • user 实现了 GetKey[int64] 接口,而 address 实现了 GetKey[int] 接口

 6.列表转集合函数

func listToMap[k comparable, T GetKey[k]](list []T) map[k]T {
    mp := make(MapT[k, T], len(list))
    for _, data := range list {
        mp[data.Get()] = data
    }
    return mp
}
  • listToMap 是一个泛型函数,将 list 转换为 map
  • 函数参数 k 为键的类型,T 为实现 GetKey[k] 接口的类型
  • data.Get() 返回键,作为 map 的键

 7.主函数 InterfaceCase

func InterfaceCase() {
    userList := []GetKey[int64]{
        user{ID: 1, Name: "张三", Age: 18},
        user{ID: 2, Name: "李四", Age: 19},
    }
    addrList := []GetKey[int]{
        address{ID: 1, Province: "广东", City: "揭阳"},
        address{ID: 2, Province: "湖南", City: "长沙"},
    }
    userMp := listToMap[int64, GetKey[int64]](userList)
    fmt.Println(userMp)
    addrMp := listToMap[int, GetKey[int]](addrList)
    fmt.Println(addrMp)
}
  • 创建 userList 和 addrList,分别包含 user 和 address 结构体
  • 调用 listToMap 将列表转换为 map,并打印结果

>>分解解读

(1)创建 user 结构体实例

user{ID: 1, Name: "张三", Age: 18},
user{ID: 2, Name: "李四", Age: 19},
  • user{ID: 1, Name: "张三", Age: 18} 创建一个 user 实例,ID 为 1,名字为 "张三",年龄为 18
  • user{ID: 2, Name: "李四", Age: 19} 创建一个 user 实例,ID 为 2,名字为 "李四",年龄为 19

 (2)实现 GetKey[int64] 接口

  • 上述 user 结构体实现了 GetKey[int64] 接口,因为 user 结构体定义了 Get() 方法,并且返回值类型为 int64

 (3)创建并初始化切片

userList := []GetKey[int64]{
    user{ID: 1, Name: "张三", Age: 18},
    user{ID: 2, Name: "李四", Age: 19},
}
  • 使用两个 user 实例来初始化一个切片 (slice)。
  • 该切片的类型是 []GetKey[int64],表示这个切片包含实现了 GetKey[int64] 接口的元素。

(4)作用

  • 创建并初始化一个包含多个 user 实例的切片,让这个切片可以作为 GetKey[int64] 接口的实现来传递和使用。
  • 这样的设计允许切片中的每个 user 实例都具备 Get 方法,从而可以在后续的泛型函数 listToMap 中使用这些 Get 方法来获取唯一键。

总结

  • GetKey 是一个泛型接口,带有类型参数 T,该参数必须是可比较类型。
  • 该接口要求实现者提供一个 Get 方法,返回类型为 T
  • 这是 Go 1.18 引入的泛型特性,允许编写更通用、更类型安全的代码。

相关知识点

接口 

  • 接口定义了方法集合,任意类型只要实现了这些方法,就实现了该接口

泛型 

  • 泛型允许定义通用的数据结构和函数,提高代码复用性。Go 1.18 开始引入泛型支持
  • 泛型接口和方法通过类型参数进行约束

结构体

  • 结构体是复合数据类型,将相关数据组织在一起

map

  • map 在 Go 中用于存储键值对,是内建的数据结构

导入包

  • fmt 包提供了格式化输入和输出功能,用于打印变量的值

(三)  示例3

package _receiver

import "fmt"

// 定义一个泛型结构体 MyStruct
// 该结构体接受一个类型参数 T,T 只能是 *int 或 *string
type MyStruct[T interface{ *int | *string }] struct {
	Name string // 结构体的名字字段
	Data T      // 结构体的数据字段,类型为 T
}

// 定义 MyStruct 结构体的泛型方法接收器
// GetData 返回结构体中的 Data 字段
func (myStruct MyStruct[T]) GetData() T {
	return myStruct.Data
}

// 主函数,演示 MyStruct 结构体和其方法的使用
func ReceiverCase() {
	// 定义一个整型变量,并创建 MyStruct 实例
	data := 18
	myStruct := MyStruct[*int]{
		Name: "heheda",
		Data: &data, // 将整型变量的指针分配给 Data 字段
	}
	// 调用 GetData 方法获取 Data 字段的值并打印
	data1 := myStruct.GetData()
	fmt.Println(*data1) // 解引用指针打印值,输出 18

	// 定义一个字符串变量,并创建 MyStruct 实例
	str := "abcdefg"
	myStruct1 := MyStruct[*string]{
		Name: "heheda",
		Data: &str, // 将字符串变量的指针分配给 Data 字段
	}
	// 调用 GetData 方法获取 Data 字段的值并打印
	str1 := myStruct1.GetData()
	fmt.Println(*str1) // 解引用指针打印值,输出 "abcdefg"
}

这段代码展示了如何在 Go 语言中使用泛型定义结构体和方法接收器,以下是对代码各部分的解释:

1.包和导入

package _receiver

import "fmt"

导入 fmt 包用于格式化输入输出

2.定义泛型结构体

type MyStruct[T interface{ *int | *string }] struct {
    Name string
    Data T
}
  • MyStruct 是一个泛型结构体,结构体内包含两个字段:Name(类型为 string)和 Data(泛型类型 T
  • 这里 T 被约束为 *int 或 *string 类型

 3.定义泛型方法接收器

func (myStruct MyStruct[T]) GetData() T {
    return myStruct.Data
}
  • GetData 是 MyStruct 的方法,这个方法接受一个泛型类型 T,返回 MyStruct 结构体中的 Data 字段

 4.主函数 ReceiverCase

func ReceiverCase() {
    data := 18
    myStruct := MyStruct[*int]{
        Name: "heheda",
        Data: &data,
    }
    data1 := myStruct.GetData()
    fmt.Println(*data1)

    str := "abcdefg"
    myStruct1 := MyStruct[*string]{
        Name: "heheda",
        Data: &str,
    }
    str1 := myStruct1.GetData()
    fmt.Println(*str1)
}
  • 创建一个整型变量 data 并取其指针赋值给 MyStruct 实例 myStruct 的 Data 字段
  • 调用 GetData 方法获取 Data 字段的值并打印
  • 创建一个字符串变量 str 并取其指针赋值给 MyStruct 实例 myStruct1 的 Data 字段
  • 调用 GetData 方法获取 Data 字段的值并打印

相关知识点

(1)泛型

  • 泛型允许定义通用的数据结构和函数,增强代码复用性。Go 1.18 开始引入泛型支持
  • 泛型类型参数通过类型约束进行限制,如本例中的 interface{ *int | *string }

(2)结构体

  • 结构体是一种复合数据类型,可以包含多个字段,允许将相关的数据组织在一起

(3)方法接收器

  • 方法接收器是指与某个类型(如结构体或接口)关联的方法。在本例中,我们定义了 MyStruct 类型的泛型方法接收器 GetData

(4)指针

  • 指针保存了变量的内存地址,在 Go 中,使用 & 符号获取一个变量的指针,使用 * 符号解引用指针获取指针指向的值

(5)导入包

  • fmt 包提供了格式化输入和输出功能,用于打印变量的值

可以尝试运行和修改代码,进一步理解这些概念。

main.go

package main

import (
	"context"
	_case "gomod/genetic-T/case"
	"os"
	"os/signal"
)

func main() {
	_case.TTypeCase()
	_case.TTypeCase1()
	_case.InterfaceCase()
	_receiver.ReceiverCase()
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
	defer stop()
	<-ctx.Done()
}

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

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

相关文章

83. UE5 RPG 实现属性值的设置

在前面&#xff0c;我们实现了角色升级相关的功能&#xff0c;在PlayerState上记录了角色的等级和经验值&#xff0c;并在变动时&#xff0c;通过委托广播的形式向外广播&#xff0c;然后在UI上&#xff0c;通过监听委托的变动&#xff0c;进行修改等级和经验值。 在这一篇里&a…

GoogleCTF2023 Writeup

GoogleCTF2023 Writeup Misc NPC Crypto LEAST COMMON GENOMINATOR? Web UNDER-CONSTRUCTION NPC A friend handed me this map and told me that it will lead me to the flag. It is confusing me and I don’t know how to read it, can you help me out? Attach…

Unity 批处理详讲(含URP)

咱们在项目中&#xff0c;优化性能最重要的一个环节就是合批处理&#xff0c;&#xff0c;在早期Unity中&#xff0c;对于合批的处理手段主要有三种&#xff1a; Static Batching Dynamic Batching GPU Instancing 如今Unity 为了提升合批范围与效率&#xff0c;提供了…

昇思 25 天学习打卡营第 15 天 | mindspore 实现 VisionTransformer 图像分类

1. 背景&#xff1a; 使用 mindspore 学习神经网络&#xff0c;打卡第 15 天&#xff1b;主要内容也依据 mindspore 的学习记录。 2. Vision Transformer 介绍&#xff1a; mindspore 实现 VisionTransformer 图像分类&#xff1b;VisionTransformer 论文地址 VisionTransfo…

掌握Python:三本不可错过的经典书籍

强烈推荐Python初学者用这三本书入门! Python3剑客 一、《Python编程从入门到实践》 这本书适合零基础的Python读者&#xff0c;旨在帮助他们快速入门Python编程&#xff0c;并达到初级开发者的水平。书中深入浅出地介绍了Python的基础概念&#xff0c;如变量、循环、函数等…

华清数据结构day4 24-7-19

链表的相关操作 linklist.h #ifndef LINKLIST_H #define LINKLIST_H #include <myhead.h> typedef int datatype; typedef struct Node {union{int len;datatype data;};struct Node *next; } Node, *NodePtr;NodePtr list_create(); NodePtr apply_node(datatype e); …

开源XDR-SIEM一体化平台 Wazuh (1)基础架构

简介 Wazuh平台提供了XDR和SIEM功能&#xff0c;保护云、容器和服务器工作负载。这些功能包括日志数据分析、入侵和恶意软件检测、文件完整性监控、配置评估、漏洞检测以及对法规遵从性的支持。详细信息可以参考Wazuh - Open Source XDR. Open Source SIEM.官方网站 Wazuh解决…

秒懂C++之string类(上)

目录 一.string类的常用接口说明 二.不太常用接口&#xff08;了解接口&#xff09; 三.string类的遍历访问 3.1 迭代器iterator 3.2 反向迭代器 四.string的其他功能 4.1 reserve(扩容&#xff09; 4.2 resize 4.3 at 4.4 append 4.5 4.6 insert 一.string类的常用…

VS2015加断点(红色),修改过后,断点变为白色不能命中

实际这个问题是因为&#xff1a;源文件和原始版本不同。解决方法有二&#xff1a; 一&#xff0c;在断点上右键&#xff0c;选择“位置”》勾选”允许源代码与原始版本不同&#xff1b; 二&#xff0c;点击菜单栏“调试”》“选项和设置”》“常规”》去掉“要求源文件与原始…

外卖霸王餐运营规划,系统该怎么选择?

在当今的外卖市场中&#xff0c;竞争日益激烈&#xff0c;如何吸引并留住消费者成为了每个餐饮商家关注的焦点。霸王餐作为一种创新的营销策略&#xff0c;以其独特的魅力&#xff0c;吸引了大量消费者的目光。然而&#xff0c;如何有效地运营霸王餐活动&#xff0c;选择合适的…

浅谈断言之XML Schema断言

浅谈断言之XML Schema断言 “XML Schema断言”是一种专门用于验证基于XML的响应是否遵循特定XML Schema定义的标准和结构的断言类型。下面我们将详细探讨XML Schema断言的各个方面。 XML Schema断言简介 XML Schema断言&#xff08;XML Schema Assertion&#xff09;允许用户…

EXO项目解析:pynvml怎么实现监控的,包括什么参数

目录 pynvml怎么实现监控的,包括什么参数 pynvml实现监控的方式 pynvml包括的主要参数 GPU功耗的组成 举例说明 注意事项 EXO项目解析:https://github.com/exo-explore/exo?tab=readme-ov-file 这段代码是一个使用setuptools库编写的Python包安装脚本,主要用于定义和…

std的时间函数——chrono

参考&#xff1a; C 标准库 分数运算&#xff08;ratio库&#xff09; 再也不被时间束缚&#xff1a;C stdchrono时间库全面解析 C11时间类 c11 chrono全面解析(最高可达纳秒级别的精度) C std::chrono库使用指南 (实现C 获取日期,时间戳,计时等功能) 一、std的分数ratio…

Android 防止重复点击

1.第一种方式&#xff1a; private static final int MIN_DELAY_TIME 2000; // 两次点击间隔不能少于2000ms private static long lastClickTime System.currentTimeMillis(); public static boolean isFastClick() { boolean flag true; long currentClickTime …

JMeter接口测试-3.断言及参数化测试

1. 断言 JMeter官方断言&#xff08;Assertion&#xff09;的定义 用于检查测试中得到的响应数据是否符合预期&#xff0c;用于保证测试过程中的数据交互与预期一致 断言的目的&#xff1a; 一个取样器可以添加多个不同形式的断言&#xff0c;根据你的检查需求来添加相应的…

dou dian滑块captchaBody

声明(lianxi a15018601872) 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言(lianxi a…

基于生物地理算法的MLP多层感知机优化matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 生物地理算法&#xff08;BBO&#xff09;原理 4.2 多层感知机&#xff08;MLP&#xff09; 4.3 BBO优化MLP参数 5.完整程序 1.程序功能描述 基于生物地理算法的MLP多层感知机优化mat…

Git之repo sync -l与repo forall -c git checkout用法区别(四十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Java 集合框架:TreeMap 的介绍、使用、原理与源码解析

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 021 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

SpringBoot原理解析(二)- Spring Bean的生命周期以及后处理器和回调接口

SpringBoot原理解析&#xff08;二&#xff09;- Spring Bean的生命周期以及后处理器和回调接口 文章目录 SpringBoot原理解析&#xff08;二&#xff09;- Spring Bean的生命周期以及后处理器和回调接口1.Bean的实例化阶段1.1.Bean 实例化的基本流程1.2.Bean 实例化图例1.3.实…