Golang基础-10

【Go语言学习系列10】Go基础语法(八):接口 深入解析Go语言接口的工作原理、类型断言与实战应用技巧,掌握这一强大的抽象机制,提升代码灵活性与可维护性 阅读详情

Go语言基础

介绍

基础

介绍

  • 本文介绍Go语言中方法定义、方法调用、String方法、结构体嵌套方法调用、方法初始化变量、接口定义、接口声明、接口变量赋值、接口的嵌套、类型断言、匿名接口与空接口等相关知识。

基础

方法
  • 方法是对类型定义的,且只能由该类型调用的函数。
  • 通过 type 自定义类型(结构体或任何自定义的类型),可对此类型定义方法。* 方法具有特定接收者(附加的类型),接收者可以是指针或值类型。
  • 函数不属于任何类型,方法指定特定的接收者类型。
// 方法的一般格式
func (t *T或T) MethodName(参数列表) (返回值列表) {
    // 方法体
}
方法定义
  • 方法必须是自定义类型,Go语言内置类型不支持用户对此类型拓展方法,使用 type 对内置类型自定义别名,自定义后的别名可以定义方法。
  • 方法声明要与接收者参数的基类型声明放在同一个包内。
type Cpu struct {
	Name string
	Id   int
}

// 接收者为值类型
func (c Cpu) GetName() string {
	return c.Name
}

func (c Cpu) GetId() int {
	return c.Id
}

// 接收者为指针类型
func (c *Cpu) PGetName() string {
	return c.Name
}

func (c *Cpu) PGetId() int {
	return c.Id
}
方法调用
  • 定义类型对象,调用类型方法时使用其对象调用。
  • 指针类型对象,调用接收者为值类型方法时,Go 编译器会自动将指针对象解引用为值调用方法。
  • 值类型对象,调用接收者为指针类型方法时,Go 编译器会自动将值对象取引用为指针调用方法。
  • 实际使用时若存在指针接收者,则所有方法使用指针接收者,否则都是用值接收者。
  • 接收者为指针类型的方法,运行时必须确保接收者不为 nil。
package main

import "fmt"

type Cpu struct {
	Name string
	Id   int
}

func (c Cpu) GetName() string {
	return c.Name
}

func (c Cpu) GetId() int {
	return c.Id
}

func (c *Cpu) PGetName() string {
	return c.Name
}

func (c *Cpu) PGetId() int {
	return c.Id
}

func main() {
	// 定义结构体对象
	cpu := Cpu{
		"Intel",
		10001,
	}
	fmt.Print("Name = ", (&cpu).PGetName()) // 常用写法 cpu.PPGetName()
	fmt.Println(", Id = ", cpu.GetId())

	// 定义结构体对象指针
	cpu2 := &Cpu{
		"AMD",
		10002,
	}

	// 两种方式均可调用
	fmt.Print("Name = ", (*cpu2).GetName())
	fmt.Println(", Id = ", cpu2.PGetId())
}

输出结果
Name = Intel, Id = 10001
Name = AMD, Id = 10002

String方法
  • 对于自定义结构体类型,通过实现 String 方法,就能调用 fmt.Println 函数输出结构体信息。
package main

import "fmt"

type Cpu struct {
	Name string
	Id   int
}

func main() {
	// 定义结构体对象
	cpu := Cpu{
		"Intel",
		10001,
	}
	fmt.Print(&cpu)
}

func (c *Cpu) String() string {
	ret := fmt.Sprintf("Name = %v, Age = %v", c.Name, c.Id)
	return ret
}

输出结果
Name = Intel, Age = 10001

结构体嵌套方法调用
  • 结构体嵌套有两种方式,匿名嵌套与命名嵌套。
  • 命名嵌套时,通过嵌套结构体的对象可以调用嵌套结构体的方法。
  • 匿名嵌套时,通过被嵌套结构体的对象可直接调用嵌套结构体的方法,若被嵌套结构体和嵌套结构体之间有同名方法,则无法调用到匿名嵌套结构体中的函数,此时就需要指定命名嵌套方式。
package main

import "fmt"

type Base struct {
	name string
}

func (b Base) GetName() string {
	return b.name
}

type Intel struct {
	base Base
	id   int
}

func (i Intel) GetName() string {
	ret := fmt.Sprintf("name = %v, id = %v", i.base.GetName(), i.id)
	return ret
}

type Amd struct {
	Base
	id int
}

// 定义此方法,编译通过,运行时报错
// func (a Amd) GetName() string {
// 	ret := fmt.Sprintf("name = %v, id = %v", a.GetName(), a.id)
// 	return ret
// }

func main() {
	// 定义结构体对象
	a := Intel{
		Base{"Intel"},
		10001,
	}
	fmt.Println(a)
	fmt.Println("a.GetName: ", a.GetName())
	fmt.Println("a.base.GetName: ", a.base.GetName())

	b := Amd{
		Base{"AMD"},
		10002,
	}
	fmt.Println(b)
	fmt.Println("b.GetName: ", b.GetName())
}

输出结果
{{Intel} 10001}
a.GetName: name = Intel, id = 10001
a.base.GetName: Intel
{{AMD} 10002}
b.GetName: AMD

方法初始化变量
  • 将方法可以作为类型初始化变量,然后使用此变量调用方法,可以存储,也可以作为形参传递或作为函数返回值。
  • 方法表达式赋值时,若方法接收者为值类型,赋值时拷贝值类型,若方法接收者为指针类型,会自动解引用拷贝。
package main

import "fmt"

type Base struct {
	name string
}

func (b Base) GetName() string {
	return b.name
}

func (b *Base) SetName(nm string) {
	b.name = nm
}

func Test(f func() string) {
	fmt.Println(f())
}

func Test2(str string, f func(string)) {
	f(str)
}

func main() {
	// 定义结构体对象
	a := Base{
		"Intel",
	}
	// 定义结构体对象,调用接收者为值的方法
	aa := a.GetName
	fmt.Printf("aa type: %T, value: %v\n", aa, aa())

	// 定义结构体对象,调用接收者为指针的方法
	ab := a.SetName
	fmt.Printf("ab type: %T", ab)
	ab("AMD")
	fmt.Printf(", value: %v\n", a.GetName())

	// 方法作为形参值传递
	Test(a.GetName)
	Test2("Intel+", a.SetName)
	Test(a.GetName)
}

输出结果
aa type: func() string, value: Intel
ab type: func(string), value: AMD
AMD
Intel+


接口
  • Go语言使用组合实现面向对象的概念。接口是自定义类型,是对其他类型行为的抽象。将不同的类型绑定到一组公共的方法上,实现多态和灵活的设计。
  • Go语言的接口设计是非侵入式的,接口定义者不需要关注什么类型实现此接口,接口实现者只需要实现对应接口,通过编译器编译时自动获取到某类型使用某接口。
  • Go 语言中的接口是隐式实现的,如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口。可以通过接口实现多态。
  • 可以存在空接口,Go语言中, 类型interface{}(any)每个类型都默认会实现,所以此类型可转换为任意类型。
type 接口类型名 interface {
    方法名1(参数列表1) 返回值列表1
    方法名2(参数列表2) 返回值列表2
    ...
}
接口定义
  • 使用 interface 关键字定义,声明了一系列的函数签名(函数名、函数参数、函数返回值)。
type GameRole interface {
	Attack(att int) error
	Cure(cur int) error
	Visit(msg string) error
}
接口声明
  • 将变量名类型定义为接口名称,变量默认初始化为 nil。
package main

import "fmt"

type GameRole interface {
	Attack(att int) error
	Cure(cur int) error
	Visit(msg string) error
}

func main() {
	var a GameRole
	fmt.Printf("a type: %T, value: %v\n", a, a)
}

输出结果
a type: , value:

接口变量赋值
  • 接口变量赋值前提是需要实现接口,且接口的方法与实现接口的类型方法格式一样,而且接口中声明的所有函数均需要被实现。

  • 当自定义类型实现了接口类型中声明的所有函数时,该类型的对象可以赋值给接口变量。

  • 方法接收者都为值类型。

package main

import "fmt"

// 定义接口
type GameRole interface {
	Attack(att int) error
	Cure(cur int) error
	Visit(msg string) error
}

// 定义结构体类型
type Warcraft struct {
	name    string
	lifeBar int
}

// 实现所有接口方法
func (c Warcraft) Attack(att int) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Attack: ", att)
	return nil
}
func (c Warcraft) Cure(cur int) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Cure: ", cur)
	return nil
}
func (c Warcraft) Visit(msg string) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Visit: ", msg)
	return nil
}

func main() {
	var a GameRole
	fmt.Printf("a type: %T, value: %v\n", a, a)

    // 接收者都为值类型
	var b GameRole = Warcraft{"Warcraft-2", 200}
	fmt.Printf("b type: %T, value: %v\n", b, b)

    // 方法调用
	b.Attack(10)
	b.Cure(5)
	b.Visit("World")
}

a type: , value:
b type: main.Warcraft, value: {Warcraft-2 200}
Warcraft-2 , 200 , Attack: 10
Warcraft-2 , 200 , Cure: 5
Warcraft-2 , 200 , Visit: World

  • 方法接收者都为指针类型。
package main

import "fmt"

type GameRole interface {
	Attack(att int) error
	Cure(cur int) error
	Visit(msg string) error
}

type Warcraft struct {
	name    string
	lifeBar int
}

func (c *Warcraft) Attack(att int) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Attack: ", att)
	return nil
}
func (c *Warcraft) Cure(cur int) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Cure: ", cur)
	return nil
}
func (c *Warcraft) Visit(msg string) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Visit: ", msg)
	return nil
}

func main() {
	var a GameRole
	fmt.Printf("a type: %T, value: %v\n", a, a)

	var b GameRole = &Warcraft{"Warcraft-2", 200}
	fmt.Printf("b type: %T, value: %v\n", b, b)

	b.Attack(10)
	b.Cure(5)
	b.Visit("World")
}

输出结果
a type: , value:
b type: *main.Warcraft, value: &{Warcraft-2 200}
Warcraft-2 , 200 , Attack: 10
Warcraft-2 , 200 , Cure: 5
Warcraft-2 , 200 , Visit: World

  • 方法接收者即有值又有指针类型,接口变量赋值需要使用指针赋值方式。
  • 一个类型可用同时实现多个接口,接口间彼此独立。
  • 只要某个类型实现一个或多个接口声明的所有函数,就可以赋值给各自的接口类型。
package main

import "fmt"

// 定义接口类型
type GameRole interface {
	Attack(att int) error
	Cure(cur int) error
	Visit(msg string) error
}

// 定义接口类型
type GameExit interface {
	ExitGame() error
}

// 定义结构体
type Warcraft struct {
	name    string
	lifeBar int
}

// 实现接口
func (c Warcraft) Attack(att int) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Attack: ", att)
	return nil
}
func (c Warcraft) Cure(cur int) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Cure: ", cur)
	return nil
}
func (c *Warcraft) Visit(msg string) error {
	fmt.Println(c.name, ", ", c.lifeBar, ", Visit: ", msg)
	return nil
}

func (c Warcraft) ExitGame() error {
	fmt.Println(c.name, ", ", c.lifeBar, ", ExitGame")
	return nil
}

func main() {
	var a GameRole
	fmt.Printf("a type: %T, value: %v\n", a, a)

	var b GameRole = &Warcraft{"Warcraft-2", 200}
	fmt.Printf("b type: %T, value: %v\n", b, b)

	b.Attack(10)
	b.Cure(5)
	b.Visit("World")

	var c GameExit = Warcraft{"Warcraft-3", 200}
	c.ExitGame()
}

输出结果
a type: , value:
b type: *main.Warcraft, value: &{Warcraft-2 200}
Warcraft-2 , 200 , Attack: 10
Warcraft-2 , 200 , Cure: 5
Warcraft-2 , 200 , Visit: World
Warcraft-3 , 200 , ExitGame

  • 当接口之间存在子集关系(一个接口(A)包含另一个接口(B)中的所有声明函数)时,A接口变量可以赋值给B接口变量。若两个接口声明同样的函数签名,两个接口完全等价。
  • 接口变量声明为什么类型就调用此类型的方法。
package main

import "fmt"

// 定义接口类型
type ExitALL interface {
	GameExit() error
	ViewExit() error
}

// 定义接口类型
type GameExit interface {
	GameExit() error
}

// 定义接口类型
type CarGameExit interface {
	GameExit() error
}

// 定义结构体
type AppExit struct {
	name string
}

// 实现接口
func (c AppExit) GameExit() error {
	fmt.Println(c.name, " game exit now")
	return nil
}

func (c AppExit) ViewExit() error {
	fmt.Println(c.name, " view exit now")
	return nil
}

func main() {
	var a ExitALL = AppExit{"TV"}
	fmt.Printf("a type: %T, value: %v\n", a, a)
	var b GameExit = AppExit{"SV"}
	fmt.Printf("b type: %T, value: %v\n", b, b)

	// GameExit 接口为 ExitALL 接口的子集
	var c GameExit = a
	fmt.Printf("c type: %T, value: %v\n", c, c)

	// GameExit 和 CarGameExit 具有相同的接口,两者完全等价
	var d CarGameExit = b
	fmt.Printf("d type: %T, value: %v\n", d, d)

	a.GameExit()
	b.GameExit()
	c.GameExit()
	d.GameExit()
}

输出结果
a type: main.AppExit, value: {TV}
b type: main.AppExit, value: {SV}
c type: main.AppExit, value: {TV}
d type: main.AppExit, value: {SV}
TV game exit now
SV game exit now
TV game exit now
SV game exit now

接口的嵌套
  • 接口间可以嵌套组合,将多个接口放到一个接口中。
package main

import "fmt"

// 定义接口类型
type FileRead interface {
	Read(read *[]byte) (int, error)
}

type FileWrite interface {
	Write(msg string) (int, error)
}

type FileClose interface {
	Close() error
}

type FileOpen interface {
	Open() error
}

// 定义接口嵌套
type FileOpt interface {
	FileRead
	FileWrite
	FileOpen
	FileClose
}

// 定义结构体
type File struct {
	path   string
	handle *int
}

// 实现接口
func (c *File) Read(read *[]byte) (int, error) {
	if c.handle == nil || len(*read) < 1 {
		return -1, fmt.Errorf("handle == nil")
	}

	var lens int = 0
	arr := [...]byte{'1', '2', '3', '4'}
	if len(arr) > len(*read) {
		lens = len(*read)
	} else {
		lens = len(arr)
	}

	fmt.Println("file handle: ", c.handle, " read byte size: ", lens)
	*read = arr[:lens]
	return lens, nil
}
func (c *File) Write(msg string) (int, error) {
	if c.handle == nil {
		return -1, fmt.Errorf("handle == nil")
	}
	fmt.Println("file handle: ", c.handle, " wirte msg: ", msg)
	return len(msg), nil
}
func (c *File) Open() error {
	c.handle = new(int)
	*c.handle = 1
	fmt.Println("Open ", c.path, " succeed")
	return nil
}
func (c *File) Close() error {
	if c.handle == nil {
		return nil
	}

	c.handle = nil
	fmt.Println("Close ", c.path, " succeed")
	return nil
}

func main() {
	// 声明接口变量
	var a FileOpt = &File{"./AppFile.txt", nil}
	fmt.Printf("a type: %T, value: %v\n", a, a)

	// 调用Open方法
	if err := a.Open(); err != nil {
		fmt.Println("Open file failed")
		return
	}

	// 延迟调用Close方法
	defer a.Close()

	var lens int = 0

	// 调用Write方法
	lens, _ = a.Write("WriteData")
	fmt.Println("write data len: ", lens)

	b := []byte{10, 20, 30, 40}
	// 调用Read方法
	lens, _ = a.Read(&b)
	fmt.Printf("b type: %T, value: %v, read data len: %v\n", b, b, lens)
}

输出结果
a type: *main.File, value: &{./AppFile.txt }
Open ./AppFile.txt succeed
file handle: 0xc00000a0d0 wirte msg: WriteData
write data len: 9
file handle: 0xc00000a0d0 read byte size: 4
b type: []uint8, value: [49 50 51 52], read data len: 4
Close ./AppFile.txt succeed

类型断言
  • 接口变量赋值时使用类型对象或将父集接口赋值给子集变量后,如果需要将接口变量重新还原为原来的类型,使用类型断言。语法:接口变量.(Type)。
package main

import "fmt"

// 定义接口类型
type ExitALL interface {
	GameExit() error
	ViewExit() error
}

// 定义接口类型
type GameExit interface {
	GameExit() error
}

// 定义接口类型
type CarGameExit interface {
	GameExit() error
}

// 定义结构体
type AppExit struct {
	name string
	id   int
}

// 实现接口
func (c AppExit) GameExit() error {
	fmt.Println(c.name, " game exit now")
	return nil
}

func (c AppExit) ViewExit() error {
	fmt.Println(c.name, " view exit now")
	return nil
}

func main() {
	var a ExitALL = AppExit{"TV", 10}
	fmt.Printf("a type: %T, value: %v\n", a, a)
	var b GameExit = AppExit{"SV", 10}
	fmt.Printf("b type: %T, value: %v\n", b, b)

	// GameExit 接口为 ExitALL 接口的子集
	var c GameExit = a
	fmt.Printf("c type: %T, value: %v\n", c, c)

	m1, ok1 := a.(AppExit)
	fmt.Println("m1: ", m1, ", ok1: ", ok1)

	m2, ok2 := b.(*AppExit)
	fmt.Println("m2: ", m2, ", ok2: ", ok2)

	m3, ok3 := c.(ExitALL)
	fmt.Println("m3: ", m3, ", ok3: ", ok3)
}

输出结果
a type: main.AppExit, value: {TV 10}
b type: main.AppExit, value: {SV 10}
c type: main.AppExit, value: {TV 10}
m1: {TV 10} , ok1: true
m2: , ok2: false
m3: {TV 10} , ok3: true

  • 通过 switch-case 语句查询变量类型,执行对应的操作。语法:接口变量.(type),case分支中不允许写 fallthrough 关键字。
package main

import (
	"fmt"
	"reflect"
)

// 定义接口类型
type ExitALL interface {
	GameExit() error
	ViewExit() error
}

// 定义接口类型
type GameExit interface {
	GameExit() error
}

// 定义接口类型
type CarGameExit interface {
	GameExit() error
}

// 定义结构体
type AppExit struct {
	name string
	id   int
}

// 实现接口
func (c AppExit) GameExit() error {
	fmt.Println(c.name, " game exit now")
	return nil
}

func (c AppExit) ViewExit() error {
	fmt.Println(c.name, " view exit now")
	return nil
}

func main() {
	var a ExitALL = AppExit{"TV", 10}
	fmt.Printf("a type: %T, value: %v\n", a, a)
	var b GameExit = AppExit{"SV", 10}
	fmt.Printf("b type: %T, value: %v\n", b, b)

	// GameExit 接口为 ExitALL 接口的子集
	var c GameExit = a
	fmt.Printf("c type: %T, value: %v\n", c, c)

	var e GameExit
	var d GameExit = e
	fmt.Printf("d type: %T, value: %v\n", d, d)

	// 声明切片
	var s []GameExit = []GameExit{a, b, c, d, e}
	fmt.Println(s)

	for i, v := range s {
		switch v.(type) {
		case AppExit:
			fmt.Printf("index %v, AppExit value: %v\n", i, v)
		case *AppExit:
			fmt.Printf("index %v, *AppExit value: %v\n", i, v)
		case ExitALL:
			fmt.Printf("index %v, ExitALL value: %v\n", i, v)
		case GameExit:
			fmt.Printf("index %v, GameExit value: %v\n", i, v)
		default:
			fmt.Println("index ", i, " is other type: ", reflect.TypeOf(v))
		}
	}
}

输出结果
index 0, AppExit value: {TV 10}
index 1, AppExit value: {SV 10}
index 2, AppExit value: {TV 10}
index 3 is other type:
index 4 is other type:

匿名接口与空接口
  • 将接口变量直接声明为接口的函数签名,称为匿名接口。
  • 匿名接口的使用场景一般是初始化一次接口变量。将实现此接口的类型变量赋值给此匿名接口的变量。
package main

import "fmt"

type Exit struct {
}

func (c *Exit) Close() error {
	fmt.Println("Exit Close")
	return nil
}

func main() {
	// 声明匿名接口变量
	var a interface {
		Close() error
	} = &Exit{}

	// 调用类型方法
	a.Close()
}

输出结果
Exit Close

  • Go语言中,定义 interface{} 称之为空接口,不包含任何函数签名,且空接口声明的变量可以赋值为任何类型的变量。声明函数参数类型为 interface{},用于接收任意类型的变量。在 Go1.18以后,添加了 空接口别名 any。
package main

import "fmt"

func main() {
	var a interface{} = "interface"
	var b interface{} = 10
	var c interface{} = 3.14
	var d any = [...]int{10, 20, 30}
	fmt.Println("a = ", a, ", b = ", b, ", c = ", c, ", d = ", d)
}

输出结果
a = interface , b = 10 , c = 3.14 , d = [10 20 30]

起始

【Golang学习之旅】Go 语言基础语法概览 ✅ 适合人群: Golang 新手 | 后端开发者 | 面试求职者✅ 文章亮点: 语法详解 + 实战代码 + 高质量示例✅ 目标: 10 分钟快速掌握 Golang 基础语法,助你高效写项目!Go 语言(Golang)是Google开发的一门静态强类型并发支持强语法简洁的编程语言,广泛应用于后端开发云计算微服务区块链等领域。🔹 Go 语言的 4 大核心特点:✅ 语法简洁(减少代码冗余,开发高效)✅ 高性能(比 Python 快,比 Java 简单) 阅读详情

相关推荐

模板匹配加速之金字塔分层搜索

图像金字塔是一种多分辨率图像表示方法,它通过一系列逐渐缩小或放大的图像来表示原始图像的不同尺度。高斯金字塔(Gaussian Pyramid):通过不断下采样(降采样)生成更小的图像。拉普拉斯金字塔(Laplacian Pyramid):通过高斯金字塔和差分操作生成一组残差图像。在模板匹配中,我们主要使用高斯金字塔来实现多尺度匹配。金字塔灰度模板匹配通过多尺度搜索策略,在保持较高准确率的同时显著提升匹配速度,尤其适用于:高分辨率图像处理实时检测系统移动端设备等资源受限场景。

weixin_44969144的博客 1732

Golang字符串string详解

1、 string的定义 Golang中的string的定义在reflect包下的value.go中,定义如下: StringHeader 是字符串的运行时表示,其中包含了两个字段,分别是指向数据数组的指针和数组的长度。 // StringHeader is the runtime representation of a string. // It cannot be used safely or portably and its representation may // change in a late

Peerless__的博客 1万+

ubuntu20.04下内核源码下载分析

ubuntu 20.04下内核源代码下载,配置编译环境写在前面一、安装VMware Workstation和Ubuntu20.04二、修改apt源合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 写在前面 我最近的科研工作需要使用到对ubun

冰冻三尺非一日之寒 1万+

Go 语言的字串数据类型 String

Go 中的字符串值得特别关注,因为与其他语言相比,Go 中的字符串实现方式是非常不同的。 GO 中字符串定义在双引号 "......" 之间,而不是单引号,与 JavaScript 不同。 Go 中的字符串是 ** UTF-8 ** 默认编码 这在 21 世纪的今天是非常有意义的。 由于 UTF-8 支持 ASCII字符集,因此在大多数情况下您无需担心编码问题。 但要深入了解 UTF-8 编码的工作原理,您一定要访问 这个维基百科页面。 先来写一个简单的程序。使用 string 关键字来定义 s

Mark66890620 2023

《哥谭神话-工程篇》01.Palantir 平台架构解析-混乱数据如何转化唯一真相源?

Palantir 平台的架构哲学可以概括为将洞察落地为行动,其核心是将“获取唯一真相”能力深度嵌入现有的、复杂的工作流程中,成为提升运营效率和决策质量的倍增器。

897

避坑指南:Unity新版InputSystem在移动端的5个常见问题及解决方案

本文针对Unity新版InputSystem在移动端开发中的常见问题,提供了5个关键解决方案,包括虚拟摇杆灵敏度调节、多点触控冲突处理、按钮反馈延迟优化、手势识别与陀螺仪数据融合以及Android/iOS平台差异处理。这些实战经验帮助开发者高效解决触控适配难题,提升移动游戏体验。

soda5的博客 405

c++ map 修改value_golang的常见问题:结构体引用、类型比较、map修改排序

1、结构体的内部变量在别的包调用,要注意大小写答:在struct中的属性,严格区分首字母大小写,大写为公有属性,别的包可以访问到,小写为私有,别的包访问不到。例如:package mainimport( "fmt" "reflect")type People struct{ Age int Name string}func main(){ temp := People{Age:...

weixin_39984963的博客 597

【STM32实战】利用STM32CubeMX配置PWM互补输出驱动电机

本文详细介绍了如何利用STM32CubeMX配置STM32高级定时器的PWM互补输出功能,以驱动电机等需要半桥/全桥电路的应用。通过图形化界面设置定时器参数、使能互补通道并配置关键的死区时间,结合代码示例演示了如何启动PWM输出和动态调整占空比,确保输出安全、精确的互补信号,避免MOS管直通风险,提升驱动可靠性。

weixin_29161785的博客 535

c语言结构体初始化为0_golang | Go语言入门教程——结构体初始化与继承

点击上方蓝字,关注并星标,和我一起学技术。今天是golang专题第10篇文章,我们继续来看golang当中的面向对象部分。在上一篇文章当中我们一起学习了怎么创建一个结构体,以及怎么给结构体定义函数,还有函数接收者的使用。今天我们来学习一下结构体本身的一些使用方法。初始化在golang当中结构体初始化的方法有四种。new关键字我们可以通过new关键字来创建一个结构体的实例,这种方法和其他语...

weixin_39526741的博客 1012

STM32CubeMX + HAL库避坑指南:为什么你的代码总在SystemClock_Config卡住?

本文深入剖析了STM32开发者在使用STM32CubeMX和HAL库时,代码在SystemClock_Config函数中卡死的根本原因。文章不仅指出硬件时序、Flash延迟配置等常见陷阱,更提供了从硬件设计、软件容错到深度调试的系统性解决方案,帮助开发者构建鲁棒的时钟初始化策略,彻底告别启动卡顿问题。

bb456的博客 928

Web端百度离线地图3.0实战:从零搭建到私有化部署

本文详细介绍了Web端百度离线地图3.0的完整实战流程,从核心SDK本地化、功能模块下载到地图瓦片部署。通过逐步修改代码与配置,实现在无外网环境下的私有化部署,解决了内网或网络不稳定场景下的地图应用需求,并提供了关键的避坑指南。

n7o8p的博客 714

golang数据结构初探之字符串string

字符串string string 是Go语言中的基础数据类型。 特性速览 声明 声明string变量非常简单,常见的方式有以下两种: 声明一个空字符串后再赋值 var s string s = "hello world" 需要注意的是空字符只是长度为0,但不是nil。不存在值为nil的string 使用简短变量声明: s := "hello world" //直接初始化字符串 双引号与单引号 字符串不仅可以使用双引号赋值,也可以使用反单引号赋值,它们的区别是在于对特殊字符的处理。 假如我们希望stri

Steven的专栏 7009

关于YOLOv8的面试题(持续更新中...)

本章将计划更新关于YOLOv8中可能会成为面试题的关键技术点,计划持续更新,可能想到合适的问题我就会整理下更新到本博客中。

ice 4167

100天精通Golang(基础入门篇)——第10天:Go语言中的数组

本篇文章是100天"学习Golang"系列文章的第10篇,主要介绍了Go语言中的数组以及数组的语法、多维数组、数组是值类型等内容。通过阅读本篇文章,读者能够了解到如何在Go语言中定义和使用数组,并掌握一些实用的代码技巧。Go语言是一种现代的、快速、并发的编程语言,由于其简单的语法和高效的执行效率,越来越受到广大开发者的青睐。本篇文章是100天学习Golang的第一篇,旨在为初学者提供一份关于Go语言数组的基础入门指南。我们将从数组的定义开始,详细介绍各种语法和技巧,帮助读者快速掌握Go语言数组的基础知识。

猫头虎技术团队:授渔优于赠鱼,兴趣引领智慧,探索之乐尤显珍贵。商务合作+:Libin9iOak ,万粉变现+:优快云WF,猫头虎承诺每年免费为100名C站创作者做账号流量诊断服务!全网搜:猫头虎技术团队,点击文章底部名片或直接私信我一切皆可谈,快找虎哥! 5万+

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

go基础语法10问(2)

无,recover 必须在 defer 函数中运行。recover 捕获的是祖父级调用时的异常,直接调用时无效。直接 defer 调用也是无效。defer 调用时多层嵌套依然无效。必须在 defer 函数中直接调用才有效。

viviiuw的博客 693

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

非零基础自学Golang 第10章 错误处理 10.3 Go语言宕机 & 10.4 宕机恢复

非零基础自学Golang 第10章 错误处理 10.3 Go语言宕机 & 10.4 宕机恢复

代码改变世界 726

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

go基础语法10问(1)

允许对值为 nil 的 slice 添加元素,但对值为 nil 的 map 添加元素,则会造成运行时 panic。

viviiuw的博客 341

Go语言精进之路:10个实用技巧助你快速掌握Go编程基础

Go语言作为近年来备受欢迎的编程语言,以其简洁高效、并发安全的特性赢得了众多开发者的青睐。GitHub加速计划(gola/golang)项目致力于扫清Go语言学习路上的一切障碍,提供从入门到精通的实战教程。本文将分享10个实用技巧,帮助初学者快速掌握Go编程基础,提升开发效率。 ## 1. 正确使用for range循环遍历集合 Go语言的`for range`循环是遍历数组、切片和映射的常用

gitblog_00034的博客 585

非零基础自学Golang 第10章 错误处理 10.5 Go语言错误的应用 & 10.6 小结 & 10.7 知识拓展

非零基础自学Golang 第10章 错误处理 10.5 Go语言错误的应用 & 10.6 小结 & 10.7 知识拓展

代码改变世界 560

2024年最新GO - 基础_go int(1),2024年最新10天拿到阿里Golang岗offer

【代码】2024年最新GO - 基础_go int(1),2024年最新10天拿到阿里Golang岗offer。

2401_84919679的博客 269

Go最新商用飞机表明符合性的10种方法_符合性访求 mc4(3),Golang开发需要什么基础

这十种方法从形式上可划分四大类:工程评审——MC0、MC1、MC2、MC3,试验——MC4、MC5、MC6、MC8,检查——MC7,设备合格性——MC9。MC4为“ 试验室试验” ,可在试片、零部件、分组件、完整组件和缩比模型等不同级别的试验件上进行,试验时通常会模拟和再现飞机预期的各种飞行及受载情况,比如电磁、闪电、振动、高低温等环境,以及轮胎爆破、转子爆破、鸟撞等可能碰到的情况,以验证产品的结构、功能、性能在上述各种条件情况下是否满足适航条款规定的要求,这些要求往往以结构强度、系统级和设备级要求居多。

2401_84904391的博客 1235

go语言基础10——包、go module

在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的。本文介绍了Go语言中如何定义包、如何导出包的内容及如何导入其他包。 包与依赖管理 本章学习目标 掌握包的定义和使用 掌握init初始化函数的使用 掌握依赖管理工具go module的使用 在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的。本文介绍了Go语言中如何定义包、如何导出包的内容及如何引入其他包。同时也将介绍如何在项目中使用go module管理依赖。 包(pa

一蓑烟雨任平生 978

10golang基础-Golang中的指针基础

golang学习笔记-Golang中的指针速通

FISH 373

10.Go语言基础 —— 指针

指针 指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。一个指针变量指向了一个值的内存地址。 Go语言支持指针类型T,指针的指针**T,以及包含包名前缀的package.T。 指针声明 在...

Felix 336

golang开源项目_10个开源项目证明了Google Go的强大功能

golang开源项目 如今已经狂奔了10年, Google的Go编程语言无疑已经名声大噪。 Go轻巧且易于编译,由于其慷慨的库和抽象可简化并发和分布式(读取:云)应用程序的开发,因此引起了广泛的关注。 但是,任何编程语言成功的真正衡量标准都是开发人员使用它创建的项目。 Go已证明自己是快速开发网络服务,软件基础设施项目以及各种紧凑而强大的工具的首选。 [也在InfoWorld上: Goo...

cxu0262的博客 1045

golang 笔记10 指针基础

指针基础 // Golang中的指针: // 不能进行指针运算 // 不能得到一个常量的指针 // 指针的一个高级应用是可以传递一个变量的引用 func TestPointer1(t *testing.T) { // x == *&x var x = 123 var xPointer *int = &x // int 类型指针 fmt.Printf("%d\t%p\t%p\t%d\n", x, &x, xPointer, *xPointer) fmt.Println(.

晨猫 145
上一篇: Golang基础-9
下一篇: Golang基础-11
无夜_
博客等级 码龄7年 2916粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值