struct结构体类型2 - 嵌入结构体值 指针类型区别

作者:matrix 发布时间:2023 年 7 月 7 日 分类:Golang

Golang中嵌入结构体类型有两种:值或指针

结论

创建 含内嵌指针struct实例时,必须手动声明嵌入的结构指针。

伪代码如下:

package main
type BaseDao struct{name string}

# 匿名结构体字段BaseDao 
type OptDao1 struct{BaseDao} # 嵌入值
type OptDao2 struct{*BaseDao} # 嵌入指针

func main(){
  opt := OptDao2{BaseDao:&BaseDao{}} //必须手动声明嵌入的结构指针
}

上面代码中OptDao1、OptDao2嵌入了BaseDao结构体,主要区别只有嵌入值的类型不同。值和指针区别

嵌入值

创建OptDao1对象

mOptDao1 := OptDao1{}
mOptDao1.name 

代码调用会正常,属性name会获取到空字符串

其他例:

type Base struct {
    value int
}

func (b *Base) Increase() {
    b.value++
}

type Derived struct {
    Base
}

func main() {
    d := Derived{}
    d.Increase()
    fmt.Println(d.value) // 输出 1
}

嵌入指针

创建OptDao2对象

mOptDao2 := OptDao2{}
mOptDao2.name 

上面代码调用会出现nil空指针异常,runtime error: invalid memory address or nil pointer dereference,即nil指针解引用错误。

原因是访问一个nil对象的方法或属性,这就会panic。

怎么办?

mOptDao2 := OptDao2{BaseDao:&BaseDao{}}
mOptDao2.name 

创建mOptDao2实例时必须声明嵌入的结构指针

其他例:

type Base struct {
    value int
}

func (b *Base) Increase() {
    b.value++
}

type Derived struct {
    *Base
}

func main() {
    d := Derived{Base: &Base{}}
    d.Increase()
    fmt.Println(d.value) // 输出 1
}

简而言之,选择值类型嵌入还是指针类型嵌入,主要取决于你是否需要多个实例共享同一个嵌入实例的状态。如果你需要共享状态,使用指针类型嵌入。如果你不需要共享状态,使用值类型嵌入。

一般情况下选择嵌入值即可,除非多个对象需要共享一个Base结构实例。

Golang的结构体类型struct

作者:matrix 发布时间:2023 年 6 月 24 日 分类:Golang

熟悉面向对象语言的话,Golangstruct结构体有点像面向对象编程中的。但这两者不是完全一样,只能说都有继承、封装、多态的特点。

结构体(struct)

结构体可以将零个或多个任意类型的值聚合在一起,能描述多个数据类型

type Person struct {
  name    string
  age     int
  value   string
  address string
}

成员方法和接收者

func (p *Person) setName(name string) {
  p.name = name
}

说明:
setName 为声明的方法
p *Person为接收者(指针类型)

struc类型新增成员方法的语法很另类,像是单独给struct做绑定,绑定的时候会有接收者来指定当前实例类型。

GOlang其实可以给任何类型创建成员方法:

type MyInt int
func (i MyInt) IsZero() bool{
  return i == 0
}

这里通过声明int的自定义类型MyInt,然后绑定一个成员方法。灵活~

值接收者 指针接收者

方法的接收者可以是结构体的值或者指针。上面例子的接收者是一个Person类型的指针。指针接收者的一个优点是可以直接修改接收者的字段值,还避免值的拷贝(内部实际上是拷贝的指针)。

声明为值接收者也是可以:

func (p Person) getName() string {
  return p.name
}

getName方法会在调用时复制接收者,就可能会导致性能问题。一般是建议使用指针作为接收者

小结

值接收者或者指针接收者 都能调用结构体或者内嵌结构体的方法或者属性。
给结构体绑定成员方法时,参数最好使用指针,防止值拷贝

func (this *Person) setName(name string) 


// 申明结构体struct
type Person struct {
  name    string
  age     int
  value   string
  address string
}

//结构绑定

// 给结构体绑定成员方法。 不推荐使用,内存利用低效(参数会使用值传递,会内存拷贝)
//p Person这里p表示值接收者
// func (p Person) getName() string {
// 这里的p变量指针和外部调用的mPerson不同,这里属于值拷贝!!!
//  return p.name
// }

// 给Person结构体指针绑定成员方法,同上面效果。但是参数属于引用传递
//this为指针接收者
func (this *Person) getName() string {
  return this.name
}

// 给Person结构体指针绑定方法
func (this *Person) setName(name string) {
  this.name = name
}

func main() {
  //创建实例
  // var mPerson *Person = new(Person)//返回实例指针
  // var mPerson Person = *new(Person)//返回实例
  // var mPerson Person = Person{}//返回实例
  var mPerson *Person = &Person{name: "Hi~"} //获取实例指针
  mPerson.setName("")
  fmt.Println(mPerson.getName())
}

matlab循环遍历struct结构体

作者:matrix 发布时间:2019 年 6 月 27 日 分类:零零星星

图片4911-matlab循环遍历struct结构体
matlab网络请求操作完成之后需要对返回数据读取,操作时候出现的问题就是无法循环struct数据。
因为接口一般以json数据格式返回,matlab会把Object结构处理为struct数据而无法循环读取。很多字段的时候我可不希望看到手写矩阵声明。
取struct长度的sizelength都无法正常返回其元素个数,听说它不是向量。

办法

fieldnames函数获取struct的字段field数据(返回为cell元胞数组)
之后用structName.(expression)这种操作获取动态的struct数组数据。比如struct.a等同于动态操作的struct.('a')
现在才知道文档上有,我TM竟然随便点括号猜出来的~

%声明方式1
%s = struct('a',11,'b',222)

%声明方式2
s=struct
s.a = 11
s.b = 222

% https://ww2.mathworks.cn/help/matlab/ref/struct.html

fileds = fieldnames(s);

for i=1:length(fileds)
    k = fileds(i);
    key = k{1};
    value = s.(key);

    disp(key)
    disp(value)
    disp('---')
end

% s.('a') %动态结构体引用

升级操作:自动生成对应变量

按照Struct字段自动生成对应的变量名和值

s = struct('a',11,'b',222)

fileds = fieldnames(s);

for i=1:length(fileds)
    k = fileds(i);
    key = k{1};
    value = s.(key);
    eval(['variable_',num2str(key) ' = ' num2str(value)])
end

说明:
使用eval函数动态创建variable_%s的变量。
本来在mathworks上看到有人发布过Structure fields to variables方法来自动处理struct,但是没有正版授权码 所以无法下载使用。

参考:
https://ww2.mathworks.cn/help/matlab/learn_matlab/types-of-arrays.html
https://ww2.mathworks.cn/help/matlab/ref/struct.html
https://www.ilovematlab.cn/thread-317868-1-1.html

https://ww2.mathworks.cn/matlabcentral/fileexchange/26216-structure-fields-to-variables

PEACE~