Go中赋值和转换关系

news2024/11/28 16:41:04

在这里插入图片描述

Go中的赋值跟类型转换:

在java中反射是可以获取继承关系,而go语言实际是不支持继承的,所以必须是相同的类型才能使用AssignableTo(),ConvertibleTo()

package main

import (
	"fmt"
	"reflect"
)

type User struct {
	Name string
}
func demo(){
	user:=User{
		Name:"Hello",
	}
	u:=reflect.TypeOf(user)
	user2:=User{
		Name: "world",
	}
	u1:=reflect.TypeOf(user2)
	b:=u.AssignableTo(u1)//u1类型的是否可以赋值给u2类型的---实际就是判断一下 类型1跟类型2是否是同一类型
	fmt.Println(b)
	b1:=u.ConvertibleTo(u1)//是否可以转换
	fmt.Println(b1)
}

func main() {
	demo()
}

在这里插入图片描述

Go中的伪继承

对比java中 的继承 (extends 关键字),Go中无extends关键字,这意味着Go中并没有对继承的支持。但是,Go使用interface实现的功能叫组合,Go是使用组合来实现的继承,说的更精确一点,是使用组合来代替的继承;

伪继承的实现:

話不多説,先看代码:

结构体的嵌套实现继承

package main

import "fmt"

//相当于java中的父类

type Animal struct {
	name string
}

//java中的 子类

type Cat struct {
	//我要继承 Animal
	Animal
	like string
}

//为猫定制的的方法

func (c Cat) Eat() string {
	//可以看到我们没有在Cat中声明 name属性,但是这里可以使用Animal声明的name
	fmt.Println(c.name + "爱吃" + c.like)
	return c.like
}

func (a Animal) Name() string {
	fmt.Println(a.name)
	return a.name
}

func main() {
	a := Animal{
		name: "小动物",
	}
	c := Cat{
		Animal: Animal{
			name: "小猫猫",
		}, like: "小鱼干",
	}
	fmt.Println(c.Name() + c.Eat() + a.Name())
}


这样Cat就继承了Animal中的属性name;

输出结果:
在这里插入图片描述

简单来看这种继承的方式实际就是结构体的嵌套(刚开始学,不知道这样理解是否正确)

接下来我们使用接口的方式来进行封装:

接口的方式实现继承:

package main

import "fmt"

//一个接口

type Animals interface {
	//接口中的方法
	eat()
}

//一个结构体

type Animal struct {
	name string
	like string
}
type Dog struct {
	Animal
	sleepTime int
}

type Cat struct {
	Animal
	hobby string
}
	
// Dog也实现了 eat
func (d Dog) eat() {
	fmt.Println(d.like)
}

// Cat也实现了 eat
func (c Cat) eat() {
	fmt.Println(c.like)
}

//实现接口---即实现接口中的方法eat

func (a Animal) eat() {
	fmt.Println(a.name + "爱吃" + a.like)
}

func main() {
	c := Cat{
		Animal: Animal{
			name: "小花猫",
			like: "小鱼干",
		},
		hobby: "睡觉",
	}
	d := Dog{
		Animal: Animal{
			name: "大黄狗",
			like: "大棒骨",
		},
		sleepTime: 100,
	}

	testinter(c)
	testinter(d)
}
func testinter(animals Animals){
	animals.eat()
}

简单来讲跟结构体的嵌套差不多,只不过这次是实现接口,从代码的实际应用来讲,实现接口是为了实现特定的目的,这个跟java中接口的实现的作用是差不多的功能;

接口的实现判断:

增量代码:

fmt.Println("======================")
	//获取接口的类型
	//先传 nil 进来 强转为接口的指针,再来获得 其类型
	animals := reflect.TypeOf((*Animals)(nil)).Elem()
	//判断是否实现接口
	bools:=cat.Implements(animals)

	fmt.Println(bools)

在这里插入图片描述

implements 方法要求传入Type类型
不能直接传入接口,
这里通过 将nil强制转换为 接口指针,在然后判断其类型

于是reflect.TypeOf((*Animals)(nil)) 就会看起来很怪;

增量代码:

	c:=Cat{
		Animal: Animal{},
		hobby:  "小鱼干",
	}
	cc:=reflect.ValueOf(c)
	fmt.Println(cc.IsNil())//判断 cc 是否是 nil

// IsNil reports whether its argument v is nil. The argument must be
// a chan, func, interface, map, pointer, or slice value; if it is //
not, IsNil panics. Note that IsNil is not always equivalent to a //
regular comparison with nil in Go. For example, if v was created // by
calling ValueOf with an uninitialized interface variable i, // i==nil
will be true but v.IsNil will panic as v will be the zero // Value.

源码解释告诉我们 只有是chan, func, interface, map, pointer, or slice ,否则就会报错 ,所以在使用之前要判断一下是否符合调用的条件在做处理;

当同时调用 cc.IsNil() ,cc.isValid()时会出现错误,导致程序不能正常运行—>>

panic: reflect: call of reflect.Value.IsNil on struct Value
//不能对结构的值调用reflect.Value.IsNil
goroutine 1 [running]:
reflect.Value.IsNil(...)

注销掉其中一个—>>
在这里插入图片描述
运行结果如下:
在这里插入图片描述

值转为Type


func main() {
	//返回值为Value类型
	i:=reflect.ValueOf(100)
	g:=reflect.ValueOf("abc")

    //打印的是值
	fmt.Println(i)
	fmt.Println(g)
    //可以直接强转--如果确定数据类型的话
	fmt.Println(i.Int())
	fmt.Println(g.String())

	//将Value转为Type
	h:=i.Type()
	k:=g.Type()
	//判断类型
	fmt.Println(h.Kind()==reflect.Int)
	fmt.Println(k.Kind()==reflect.String)
}

Golang中的reflect.Elem()函数用于获取接口v包含的值或指针v指向的值

调用该函数Elem()只能是接口指针

反射修改数据

通过反射可以修改原始变量的值,但是需要一定的条件支持,传入的实参必须是指针类型

package main

import (
	"fmt"
	"reflect"
)

func main(){
	//字符串
	var s ="hello"
	//这里要传指针,否则不会修改
	vs:=reflect.ValueOf(&s)
	vs.Elem().SetString("world")

	fmt.Println(s)
}

这里通过 Elem()方法把指针Value转换为非指针Value----即通过反射获取指针指向的元素类型,这个获取过程被称为取元素,等效于对指针类型变量做了一个*操作

我们来操作一下struct

package main

import (
	"fmt"
	"reflect"
)

type user struct {
	name string
	age int
}
func main(){
	//字符串
	var s ="hello"
	//这里要传指针,否则不会修改
	vs:=reflect.ValueOf(&s)
	vs.Elem().SetString("world")

	fmt.Println(s)

u:=user{
	name: "小红",
	age: 18,
}
h:=reflect.ValueOf(&u)//传指针
k:=h.Elem().FieldByName("name")//根据属性名获取值 Elem将其转为值
fmt.Println(k)
fmt.Println(k.CanSet())//只有值是可寻址的时候才可以被修改---即可以被外界访问的
if k.CanSet(){
	k.SetString("小明")
	//k.Elem().SetString("小明")
	fmt.Println(u.name)
}
}

输出结果:
在这里插入图片描述
因为这里name属性的访问权限问题,所以 canSet()的结果为false, 我们将user属性name改为"Name" 再来看输出结果—>>
在这里插入图片描述
当 我们通过反射去修改结构体中的属性时,这个属性 要是能够被访问的—即首字母大写,
如果是接口中的即使时小写的也可以被访问;

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

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

相关文章

C#语言实例源码系列-实现自定义屏保

专栏分享点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册 👉关于作者 众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中…

Class文件结构

文章目录1.概述1.1 字节码文件的跨平台性1.2 Java的前端编译器1.3 透过字节码指令看代码细节2. 虚拟机的基石:Class文件3. Class文件结构3.1 魔数3.2 Class文件版本号3.3 常量池3.4 访问标识3.5 类索引、父类索引、接口索引集合3.6 字段表集合3.7 方法表集合3.8 属性表集合4. 使…

No.178# 混沌工程相关内容梳理

引言随着公司规模业务的快速增长,数以千计甚至万计的微服务,依赖的各类组件越来越多。分布式体系架构体系越来越复杂,没有任何一个人能够掌控所有复杂的耦合性。也就是说复杂性无法避免,不可能再回到单体应用,也无法彻…

西门子精彩触摸屏SMART V3组态配方的具体方法示例

西门子精彩触摸屏SMART V3组态配方的具体方法示例 本次和大家分享在精彩系列触摸屏中进行配方组态的具体方法,以下内容仅供大家参考: 如下图所示,首先,在连接中添加新的连接,这里以S7-200SMART为例,PLC和HMI的IP地址要设置在同一网段内, 如下图所示,在变量中,添加配…

【Java面试】来讲一讲你对String的理解

文章目录字符型常量和字符串常量的区别什么是字符串常量池?String 是最基本的数据类型吗String有哪些特性String为什么是不可变的?String真的是不可变的吗?String不可变的必要性是否可以继承 String 类数组有没有 length()方法?St…

windows线程 互斥锁CreateMutex、ReleaseMutex、CloseHandle

互斥 相关问题 多线程下代码或资源的共享使用。 互斥的使用 1.创建互斥 HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes,//安全属性(废弃参数,置NULL) BOOL bInitialOwner,//初始的拥有者TRUE/FALSE LPCTSTR lpName //命名 );…

集成电路技术——如何制造芯片(1)

1.概述 电子工业是现在高新技术的核心,它在人类的科技发展中发挥了巨大作用,电子工业已经成为成为当今世界发展最快的高新技术产业,在全世界各国国民经济中起着举足轻重的作用。当今的电子技术离不开集成电路,集成电路是电子工业…

hadoop集群迁移

集群迁移 主要是要找到两个集群中active状态的namenode 集群迁移不同于服务器之间的文件发送,在hdfs中,文件是以块的形式,只可以通过namenode访问文件,所以迁移时需要通过hadoop命令 主要命令是distcp distcp有很多参数&#xf…

Kafka - 06 Kafka 集群环境搭建(三台服务器)

文章目录1. 克隆虚拟机2. Zookeeper 集群搭建3. Kafka 集群搭建4. 测试消息发送和消费1. 主题操作2. 生产者生产消息3. 消费者消费消息1. 克隆虚拟机 kafka集群搭建,需要3台虚拟机环境,但是我目前只安装了一台虚拟机,因此还需要准备两台虚拟…

[附源码]计算机毕业设计springboot-Steam游戏平台系统论文

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

纯CSS制作3D动态相册【流星雨3D旋转相册】HTML+CSS+JavaScriptHTML5七夕情人节表白网页制作

这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看。 此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个TA站在眼前都不敢向前表白…

MySQL数据库管理及用户管理以及数据库用户授权

MySQL数据库管理及用户管理以及数据库用户授权MySQL数据库管理1、库和表2、常用的数据类型查看数据库结构SQL语句1、SQL语句分类:创建及删除数据库和表管理表中的数据记录(表数据的增删改查)向数据表中插入新的数据记录(增&#x…

大二Web课程设计——动漫海贼王(可以很好的应付老师的作业)

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,有div的样式格局,这个实例比较全面,有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 精彩专栏推荐&#x1f4…

Java基础:入门程序、常量、变量

第一章 HelloWorld入门程序 1.1 程序开发步骤说明 Java程序开发三步骤:编写、编译、运行。 1.2 编写Java源程序 在D:\java\javaCode目录下新建文本文件,完整的文件名修改为HelloWorld.java,其中文件名为 HelloWorld,后 缀名必须…

音视频技术开发周刊 | 273

每周一期,纵览音视频技术领域的干货。新闻投稿:contributelivevideostack.com。「紧急通知」LiveVideoStackCon 2022 音视频技术大会北京站改期各位LVSer们:因疫情影响,北京近期不再允许举办大型线下活动,我们无奈且抱…

如何向瑞芯微平台添加驱动

如何向瑞芯微平台添加驱动驱动配置驱动文件放置配置相应的编译选项与设备树结合设备树配置以avafpga视频驱动为例:驱动配置 驱动文件放置 为了保证驱动文件能够被系统正确识别编译,需要将驱动文件的源文件avafpga.c放在./kernel/drivers/media/i2c/下 …

外观专利申请定要注意哪些因素呢?

问题一:申请外观专利需要提交哪些申请材料呢? 1、外观专利请求书; 2、外观设计七视图的照片或者设计图; 3、申请人的身份证明材料; 4、外观设计的简要说明材料。 问题二:外观专利申请定要注意哪些因素…

Automatic Online Calibration of Cameras and Lasers 论文翻译

目录题目AbstractI. INTRODUCTIONII. SENSOR PROCESSINGA. Image processingB. Laser processingIII. MISCALIBRATION DETECTIONIV. AUTOMATIC CALIBRATION TRACKINGV. EXPERIMENTAL RESULTSVI. CONCLUSION题目 Automatic Online Calibration of Cameras and Lasers 下载地址&…

C++ Reference: Standard C++ Library reference: Containers: list: list: size

C官网参考链接&#xff1a;https://cplusplus.com/reference/list/list/size/ 公有成员函数 <list> std::list::size C98 size_type size() const; C11 size_type size() const noexcept; 返回大小 返回列表&#xff08;list&#xff09;容器中的元素个数。 形参 没有…

Python tkinter -- 第18章 画布控件之图像(image)

18.2.16 create_image(position, **options) 在画布的指定位置创建一个图片对象。这里的图片对象是gif&#xff0c;png&#xff0c;pgm和ppm。 &#xff08;1&#xff09;position&#xff1a;图片的坐标(x,y)。 &#xff08;2&#xff09;**options&#xff1a;图片选项 选项…