Go语法的特殊之处

上文我们讲了GO模块引入指令Go Mod,本文讲述Go语法的特殊之处

:=

单变量 :=
hello:=“hello”
Go 语言中新增了一个特殊的运算符:=,这个运算符可以使变量在不声明的情况下直接被赋值使用。其使用方法和带值声明变量类似,只是少了var关键字,形如变量名:=变量值,这样就等于声明了一个带值的变量,该变量的类型与其变量值一致。
多变量:=

hello,world:="hello","world"

函数拥有者

func  
(p myType )  funcName ( a, b int , c string ) ( r , s int ) {
return
}

函数拥有者—(p myType) // 这个是此函数的拥有者,下面解释(此项可省略)
重点说说这个函数拥有者(p myType),这个是相较于C/C++比较特殊的地方。
为特定类型定义函数,即为类型对象定义方法
在Go中通过给函数标明所属类型,来给该类型定义方法,上面的 (p myType) 即表示给myType声明了一个方法, p myType 不是必须的。如果没有,则纯粹是一个函数。

匿名变量

dataBytes, _ := ctx.RequestBody()

匿名变量,可使用_接受不想要的变量,会直接抛弃。

强制导入

import (
    "encoding/json"
    "github.com/go-spring/spring-core/gs"
    "github.com/go-spring/spring-core/web"
    // 这里必须引入web starter, 也可改为 "github.com/go-spring/starter-echo"
    _ "github.com/go-spring/starter-gin"
    "log"
)

第六行说明,会在一开始就去加载这个包的init方法,果然能找到

func init() {
    gs.Provide(SpringGin.New, "${web.server}")
}

包的别名

import (
    SpringLogger "github.com/go-spring/go-spring-parent/spring-logger"
    SpringBoot "github.com/go-spring/go-spring/spring-boot"
)

包的别名SrpingLogger,这样的话,在用到的地方就可以按照如下方式使用

level := SpringLogger.InfoLevel

interface{}

总结:万能类型(interface{})很神奇,就像 C 里面的 void*、 像 Java 中的 Object 类型。任何变量都可以赋值给interface{}类型的变量。
工作中,当我们使用 interface{} 作为函数形参时, 我们可以传入任何类型作为参数,因为任何类型都实现了 interface{} 接口。
[]interface{}
当我们声明 interface{} 数组的时候,事情就变的不一样了
func Foo(a []interface{}) {}

Foo([]int{1, 2, 3}) // 报错
Foo([]string{“1”, “2”, “3”}) // 报错
按照本身的设想,这里应该不管什么样的数组都可以作为参数传入,可是结果却恰恰相反:我们只能传入类型为 []interface{} 的元素。
既然interface{}能代表任意类型,那么interface{}的切片为什么不能代表任意类型的切片呢?
因为 []interface{} 类型变量拥有特定的内存结构。
每个 interface{} 占两个字(32 位机器一个字是 32 位,64 位机器一个字是 64 位)。其中,一个字用于存放 interface{} 真正传入的数据的类型;另一个字用于指向实际的数据。
对于[]interface{}类型的变量来说,切片里的每个元素可以存储不同类型的变量,例如
func main() {
var a = make([]interface{}, 0)
a = append(a, []int{123, 456})
a = append(a, []string{“abc”, “ijk”})
fmt.Println(a) // [[123 456] [abc ijk]]
}

& 和 * 指针的使用

指针在Go语言中用来实现引用传递。在函数中传递某个变量时,有时我们需要传递这个变量的内存地址而不是它的副本。通过将变量的地址传递给函数,函数就可以直接操作变量的原始值,而不需要创建变量的副本,从而提高了程序的性能和效率。此外,使用指针传递变量还可以节省内存空间,尤其是在处理大型数据结构时,比如数组、切片和结构体。
符号 & 的意思是对变量取地址。
如:变量 a 的地址是 &a。
符号 * 的意思是对指针取值。
如:*&a,就是 a 变量所在地址的值,当然也就是 a 的值了。
user := &objects.User{Username: username, Age: ageInt}//指针
err = c.MySQLService.SaveUser(user)

func (myService *MySQLService) SaveUser(user *objects.User) error {
_, err := myService.UserDao.Insert(user)
if err != nil {
SpringLogger.Errorf(“SaveUser(%v),err:%v”, user, err)
return err
}
return err
}

传入的是objects.User的指针

返回值

如果是单个返回值的话
RequestBody() []byte
如果是多个返回值的话
RequestBody() ([]byte, error)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值