当前位置: 首页 > news >正文

网站主题颜色一键优化软件

网站主题颜色,一键优化软件,给我一个网页,日本a片女人和狗做的网站了解可赋值规范的重要性当使用type关键字定义类型的时候,会遇到一些问题,如下:func main(){var i int 2pushInt(i) } type MyInt int //基于int定义MyInt func pushInt(i MyInt){}结果:调用函数pushInt报错 cannot use i (variab…

了解可赋值规范的重要性

当使用type关键字定义类型的时候,会遇到一些问题,如下:

func main(){var i int = 2pushInt(i) }
type MyInt int //基于int定义MyInt
func pushInt(i MyInt){}结果:调用函数pushInt报错
cannot use i (variable of type int) 
as MyInt value in argument to pushIntcompilerIncompatibleAssign

而相似的,这种调用就不会出错:

func main(){var i []int = []int{2,3,4}pushInt(i)}type MyInt []int //基于[]int 定义MyInt
func pushInt(i MyInt){}结果:正常编译运行!!!

go语法中的赋值无处不在,赋值操作、调用方法时的receiver赋值、调用方法的parameter赋值、方法返回值的接收变量赋值,赋值即值拷贝,这个大家都懂,可是赋值的类型约束是什么?

赋值原则其实很简单

1、类型相同可以进行赋值
2、类型不同的情况,至少有一个是unnamed type,且底层类型必须兼容。

下面会慢慢讲解。

go语言规范定义

go语言规范中对可赋值的描述比较复杂,说到底就是上面的2个原则,我们先大概看一下规范内容,然后等阐明什么叫类型相同,什么叫底层类型相同,在回过头来理解该规范。

A value x of type V is assignable to a variable of type T ("x is assignable to T") if one of the following conditions applies:

  • V and T are identical.

  • V and T have identical underlying types but are not type parameters and at least one of V or T is not a named type.

  • V and T are channel types with identical element types, V is a bidirectional channel, and at least one of V or T is not a named type.

  • T is an interface type, but not a type parameter, and x implements T.

  • x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type, but not a type parameter.

  • x is an untyped constant representable by a value of type T.

Additionally, if x's type V or T are type parameters, x is assignable to a variable of type T if one of the following conditions applies:

  • x is the predeclared identifier nil, T is a type parameter, and x is assignable to each type in T's type set.

  • V is not a named type, T is a type parameter, and x is assignable to each type in T's type set.

  • V is a type parameter and T is not a named type, and values of each type in V's type set are assignable to T.

什么叫类型相同

1、named type,有名字的类型,只有名称相同才能称为类型相同

named的type包括

  • predeclared type,即程序预声明的类型,如int byte run string等,这些都是有名字的。

var x int = 20 //x的类型是named type -->int
  • defined type,即通过type关键字定义的类型,定义时根据语法是必须要给定名字的。(注意type declaration和type definition的区别)

type Dog struct{} //类型名字为Dog
type Dog int //类型名字为Dogtype Dog = int //类型名字为int(Dog只是个别名)
type Dog = struct{} //该类型是unnamed(Dog只是个别名)
  • type parameter,类型参数是泛型中的概念,其定义了新的类型,例如[T ~int],类型名为T,底层类型为int(底层类型后面讲)

func name[T ~string](dogName T){} //定义了一个新的类型T
//注意T是一个类型,而func name(T string)中,T是一个变量。
2、literal type,字面量类型没有名称,只要结构相同,类型就相同

composite类型都可以用字面量定义新的类型,如slice channel等的类型都可以用literal来定义,如下列举了几个literal类型定义:

    var x func(string) int = func(s string) int {return 1} //functionvar x struct{ name string } = struct{ name string }{"name"} //structvar x []int = []int{1,2,3} //slicevar x [3]int = [3]int{1,3,4} //arrayvar x map[int]int = make(map[int]int) //mapvar x chan int = make(chan int) //channelnum := 23var x *int = &num //pointervar x interface{String() stringName() string} = Inner{"name"} //interface

我们发现其实 指针类型、chan、map、array、slice的类型定义,我们平时都是使用unnamed的literal type 形式。因为比较方便。如果我们使用named type反而会比较麻烦

type MyMap map[int]int //这样定义类型就比较麻烦

3、规范中对类型相同的描述

以上两种已经描述何为类型相同,规范中是这样描述的:

A named type is always different from any other type. Otherwise, two types are identical if their underlying type literals are structurally equivalent; that is, they have the same literal structure and corresponding components have identical types. In detail:

  • Two array types are identical if they have identical element types and the same array length.

  • Two slice types are identical if they have identical element types.

  • Two struct types are identical if they have the same sequence of fields, and if corresponding fields have the same names, and identical types, and identical tags. Non-exported field names from different packages are always different.

  • Two pointer types are identical if they have identical base types.

  • Two function types are identical if they have the same number of parameters and result values, corresponding parameter and result types are identical, and either both functions are variadic or neither is. Parameter and result names are not required to match.

  • Two interface types are identical if they define the same type set.

  • Two map types are identical if they have identical key and element types.

  • Two channel types are identical if they have identical element types and the same direction.

  • Two instantiated types are identical if their defined types and all type arguments are identical.

4、小试牛刀(规范中的小练习)

以下类型哪些相同

type (A0 = []stringA1 = A0A2 = struct{ a, b int }A3 = intA4 = func(A3, float64) *A0A5 = func(x int, _ float64) *[]stringB0 A0B1 []stringB2 struct{ a, b int }B3 struct{ a, c int }B4 func(int, float64) *B0B5 func(x int, y float64) *A1C0 = B0D0[P1, P2 any] struct{ x P1; y P2 }E0 = D0[int, string]
)

相同的类型:

A0, A1, and []string
A2 and struct{ a, b int }
A3 and int
A4, func(int, float64) *[]string, and A5
B0 and C0
D0[int, string] and E0
[]int and []int
struct{ a, b *B5 } and struct{ a, b *B5 }
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5

B0 and B1 are different because they are new types created by distinct type definitions; func(int, float64) *B0 and func(x int, y float64) *[]string are different because B0 is different from []string; and P1 and P2 are different because they are different type parameters. D0[int, string] and struct{ x int; y string } are different because the former is an instantiated defined type while the latter is a type literal (but they are still assignable)

什么叫底层类型相同

什么叫底层类型

每种类型都有其底层类型

  • 上面提到的predeclared类型和literal类型其底层就是其本身

var x int //变量x的类型是predeclared 的int,int的底层类型是int
var x []int //类型是literal的[]int,其底层类型是[]int
  • 指向类型的底层类型,是其指向的类型的底层类型。有点拗口,上栗子

type MyInt int //MyInt指向int,int的底层类型是int,那么结果是int
type YourInt MyInt //YourInt指向MyInt,那么就是MyInt的底层类型,那么结果就是int
type HisInt YourInt //HisInt指向YourInt,以此类推,那么结果就是int
  • 类型参数的底层类型,是其约束类型。

func name[T ~string](n  T){}//类型参数定义了新的类型T,T的底层类型就是string

知道底层类型是什么,那么按第一小节“什么叫类型相同”中的规则进行对比,即可知道两个类型的底层类型是否相同。

回过来看可赋值的规范定义

下面会对规范中可赋值定义进行一句句解释:

A value x of type V is assignable to a variable of type T ("x is assignable to T") if one of the following conditions applies:

这一部分讲解非type parameter(类型参数)的情形:

  • V and T are identical.

类型相同,可以赋值
  • V and T have identical underlying types but are not type parameters and at least one of V or T is not a named type.

不是类型参数,底层类型相同,如果只有一个unnamed type那么底层类型相同,两个
都是unnamed type的话是相同类型。
  • V and T are channel types with identical element types, V is a bidirectional channel, and at least one of V or T is not a named type.

channel元素相同,底层数据类型相同。如果一个unnamed type的话,那么底层数据相同。如果两个都是
unnamed type的话,那么底层数据相同,甚至是类型完全相同。
var c <- chan int = make(chan int) //类型不同,但底层类型相同
var c chan int = make(chan int) //类型相同
  • T is an interface type, but not a type parameter, and x implements T.

x和T必须有is a的关系。
  • x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type, but not a type parameter.

x是nil,因为nil是预声明标识符,而不是类型。
可以赋值给pointer,function....(引用类型和interface类型)
  • x is an untyped constant representable by a value of type T.

x是untyped int ,是unnamed。但是和int32 底层类型相同,所以可以赋值
const x = 1 << 20 //x在初始化的时候是untyped int(x的取值范围可以超过 1<<64的而x处不会报错)
func main() {var y int32 = x}

这一部分讲解type parameter的情形:

Additionally, if x's type V or T are type parameters, x is assignable to a variable of type T if one of the following conditions applies:

  • x is the predeclared identifier nil, T is a type parameter, and x is assignable to each type in T's type set.

x是nil是标识符而不是named type,T是type parameter有名字,类型不同。
T类型参数的类型集是指针类型,可以接受nil
func name3[X *int](age X) {age = nil
}
  • V is not a named type, T is a type parameter, and x is assignable to each type in T's type set.

V是unnamed那么就不会和T的类型不同,底层类型相同即可
func name[X ~int](age X) {a := 20 + agefmt.Println(a)age = 30 // age = a会报错,因为a是named类型,而age = 30就不会报错
}
  • V is a type parameter and T is not a named type, and values of each type in V's type set are assignable to T.

age是type parameter有unnamed的,而x是literal没名字,类型不同,但底层类型一样
func name2[X IntArr](age X) {var x map[int]int = age 
}
type IntArr map[int]int

完全符合我们的可赋值原则

1、类型相同可以进行赋值

2、类型不同的情况,至少有一个是unnamed type,且底层类型必须兼容。

描述可能不够准确,望网络大佬们指正。🙅

http://www.hkea.cn/news/597047/

相关文章:

  • 建设银行网站优点做个公司网站大概多少钱
  • 网站标题的设置方法哪家建设公司网站
  • 网站空间托管电商平台的营销方式
  • 网站制作专业的公司有哪些seo网站编辑是做什么的
  • wordpress 分栏seo怎么优化简述
  • php网站开发 多少钱推广方案策划
  • 芜湖做网站公司广州seo好找工作吗
  • 做网站找客户百度竞价推广公司
  • 深圳网站建设怎么办互联网营销的优势
  • 课程网站开发背景网站推广的几种方法
  • 商城网站建设模板一份完整的营销策划方案
  • 推广网站建设网站权重查询工具
  • t型布局网站怎么做建设网官方网站
  • 哪个建设网站推广竞价托管公司
  • 网站建设傲seo网站是什么意思
  • 卢氏住房和城乡建设厅网站聚名网
  • 山东网站建设电话长沙靠谱的关键词优化
  • 山东营销型网站ip网站查询服务器
  • 什么网站上做奥数题企业培训课程清单
  • 龙岩优化seo是什么意思
  • 外贸网站建设源码软文怎么做
  • 文章列表页wordpress宁波seo资源
  • 获取网站访客qq 原理百度投诉中心人工电话
  • 企业网站制作查询百度电话怎么转人工
  • 杭州专业网站建设怎样创建网站
  • 网站建设报价表格式淘宝关键词优化技巧
  • 高端网站建设系统百度网盘登录入口官网
  • ps做网站顶部江苏网络推广公司
  • 源码做网站手机网站百度关键词排名
  • 网站关键词分隔网站链接提交