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

商铺装修seo是怎么优化推广的

商铺装修,seo是怎么优化推广的,做网站入门看什么书,出版社类网站模板Interface整理 文章目录 Interface整理接口嵌套接口类型断言类型判断 type-switch使用方法集与接口空接口实例 接口赋值给接口 接口是一种契约,实现类型必须满足它,它描述了类型的行为,规定类型可以做什么。接口彻底将类型能做什么&#xff0…

Interface整理

文章目录

  • Interface整理
    • 接口嵌套接口
    • 类型断言
    • 类型判断 type-switch
    • 使用方法集与接口
    • 空接口
      • 实例
    • 接口赋值给接口

接口是一种契约,实现类型必须满足它,它描述了类型的行为,规定类型可以做什么。接口彻底将类型能做什么,以及如何做分离开来,使得相同接口的变量在不同的时刻表现出不同的行为,这就是多态的本质。

编写参数是接口变量的函数,这使得它们更具有一般性。

使用接口使代码更具有普适性。

最近在学Go当中的接口,学的有点云里雾里 ,这个interface和Java的也太不像了,我们先来看看Java当中的接口是怎么用的:

首先我们先定义一个接口:

public interface Study {    //使用interface表示这是一个接口void study();    //接口中只能定义访问权限为public抽象方法,其中public和abstract关键字可以省略
}

之后我们用关键字继承:

public class Student extends Person implements Study {   //使用implements关键字来实现接口public Student(String name, int age, String sex) {super(name, age, sex, "学生");}@Overridepublic void study() {    //实现接口时,同样需要将接口中所有的抽象方法全部实现System.out.println("我会学习!");}
}public class Teacher extends Person implements Study {protected Teacher(String name, int age, String sex) {super(name, age, sex, "教师");}@Overridepublic void study() {System.out.println("我会加倍学习!");}

这样一个显示继承的方式非常清晰明了,接下来看看Go里面的接口:

type Namer interface {Method1(param_list) return_typeMethod2(param_list) return_type...
}

这样一看没有什么很大的区别,都需要先声明一个接口但是不使用,接下来看看接口的实现:

package mainimport "fmt"type Shaper interface {Area() float32
}type Square struct {side float32
}func (sq *Square) Area() float32 {return sq.side * sq.side
}func main() {sq1 := new(Square)sq1.side = 5var areaIntf ShaperareaIntf = sq1// shorter,without separate declaration:// areaIntf := Shaper(sq1)// or even:// areaIntf := sq1fmt.Printf("The square has area: %f\n", areaIntf.Area())
}

这样就会发现如下几个区别:

  1. 并没有显式继承
  2. 接口能声明变量,并通过该变量指向方法
  3. 实现方法中的参数为自定义的结构体

一个接口类型的变量或一个 接口值

首先我们来看第一点,关于为什么不显示继承,这一点我在网上搜过,观点基本是Go强调的是组合而非继承,并没有一个很确切的理论,那暂且不议

第二点:areaIntf是一个多字(multiword)数据结构,它的值是 nil。接口变量里包含了接收者实例的值和指向对应方法表的指针。

在Go中,我们自定义的结构体就像Java中的类一样,可以实现接口中的方法。我们可以同一个接口被实现多次。当时就有了点疑问:不是不允许函数重载吗?后来发现方法和函数是完全不同的概念:

Go中不允许函数(function)重载是为了提高效率,而方法(method)的可多次实现则体现了Go的多态,也就是根据场景选择。


接下来,我们看一些进阶功能:

接口嵌套接口

在Java 和go当中,我们都倡导一个接口的简洁明了。比如说先定义一个结构体为综测,综测又是由考试成绩、竞赛、体育等等组成,考试成绩里面又有不同科,体育里面也有不同科,这个时候我们就应该分开定义,之后进行嵌套。我个人的理解的理解就是类似于树一样的存在,而一个结构体就是一个父节点。这里还是放一个实例:

type ReadSeeker interface {ReaderSeeker
}type Reader interface {Read(p []byte) (n int, err error)
}type Seeker interface {Seek(offset int64, whence int) (int64, error)
}

类型断言

我们通常会想知道一个接口变量里面是什么类型,这个时候我们就会用到类型断言,通用格式为:

typeA := var1.(T)

var1为接口变量,T是想知道的类型。如果转换合法,typeAvar1转换到类型 T 的值

如果在判断式中使用,则是这样的:

if t, ok := areaIntf.(*Square); ok {fmt.Printf("The type of areaIntf is: %T\n", t)
}

如果转换合法,t 是 转换到类型的值,ok 会是 true;否则 t是类型的零值,okfalse,也没有运行时错误发生。

注意:如果忽略 areaIntf.(*Square) 中的 * 号,会导致编译错误:impossible type assertion: Square does not implement Shaper (Area method has pointer receiver)

同理,我们也可以判断他是否属于该接口:

type Stringer interface {String() string
}if sv, ok := v.(Stringer); ok {fmt.Printf("v implements String(): %s\n", sv.String()) // note: sv, not v
}

类型判断 type-switch

个人认为如果说类型断言是只想知道值是不是某个类型,那么此语句则是想知道究竟是哪个重要的类型或者不需要知道的类型,常见用法如下:

func classifier(items ...interface{}) {for i, x := range items {switch x.(type) {case bool:fmt.Printf("Param #%d is a bool\n", i)case float64:fmt.Printf("Param #%d is a float64\n", i)case int, int64:fmt.Printf("Param #%d is a int\n", i)case nil:fmt.Printf("Param #%d is a nil\n", i)case string:fmt.Printf("Param #%d is a string\n", i)default:fmt.Printf("Param #%d is unknown\n", i)}}
}

可以用 type-switch 进行运行时类型分析,但是在 type-switch 不允许有 fallthrough

使用方法集与接口

作用于变量上的方法实际上是不区分变量到底是指针还是值的。当碰到接口类型值时,这会变得有点复杂,原因是接口变量中存储的具体值是不可寻址的,

package mainimport ("fmt"
)type List []intfunc (l List) Len() int {return len(l)
}func (l *List) Append(val int) {*l = append(*l, val)
}type Appender interface {Append(int)
}func CountInto(a Appender, start, end int) {for i := start; i <= end; i++ {a.Append(i)}
}type Lener interface {Len() int
}func LongEnough(l Lener) bool {return l.Len()*10 > 42
}func main() {// A bare valuevar lst List// compiler error:// cannot use lst (type List) as type Appender in argument to CountInto://       List does not implement Appender (Append method has pointer receiver)CountInto(lst, 1, 10) //错误代码 if LongEnough(lst) { // VALID: Identical receiver typefmt.Printf("- lst is long enough\n")}// A pointer valueplst := new(List)CountInto(plst, 1, 10) // VALID: Identical receiver typeif LongEnough(plst) {// VALID: a *List can be dereferenced for the receiverfmt.Printf("- plst is long enough\n")}
}

输出

Untitled

讨论

lst 上调用 CountInto 时会导致一个编译器错误,因为 CountInto 需要一个 Appender,而它的方法 Append 只定义在指针上。 在 lst 上调用 LongEnough 是可以的,因为 Len 定义在值上。

plst 上调用 CountInto 是可以的,因为 CountInto 需要一个 Appender,并且它的方法 Append 定义在指针上。 在 plst 上调用 LongEnough 也是可以的,因为指针会被自动解引用。

总结

在接口上调用方法时,必须有和方法定义时相同的接收者类型或者是可以根据具体类型 P 直接辨识的:

  • 指针方法可以通过指针调用
  • 值方法可以通过值调用
  • 接收者是值的方法可以通过指针调用,因为指针会首先被解引用
  • 接收者是指针的方法不可以通过值调用,因为存储在接口中的值没有地址

将一个值赋值给一个接口时,编译器会确保所有可能的接口方法都可以在此值上被调用,因此不正确的赋值在编译期就会失败。

译注

Go 语言规范定义了接口方法集的调用规则:

  • 类型 T 的可调用方法集包含接受者为 TT 的所有方法集
  • 类型 T 的可调用方法集包含接受者为 T的所有方法
  • 类型 T 的可调用方法集包含接受者为 T 的方法

接下来我们讨论下空接口

空接口

定义:不包含任何方法,对实现没有要求

空接口类似 Java/C# 中所有类的基类: Object 类,二者的目标也很相近。

可以给一个空接口类型的变量 var val interface {} 赋任何类型的值

每个 interface {} 变量在内存中占据两个字长:一个用来存储它包含的类型,另一个用来存储它包含的数据或者指向数据的指针。

这样光看似乎觉得没什么大不了的,我们举个例子,比如说创建树或者其他数据结构,如果我们要根据每个数据类型来定义不同的方法,那无疑是很浪费时间的,这时候就可以用到空接口,实现一键通用:

package mainimport ("fmt"
)type Node struct {le   *Nodedata interface{}rl   *Node
}func NewNode(left, right *Node) *Node {return &Node{left, nil, right}
}func (n *Node) setData(data interface{}) {n.data = data
}func main() {root := NewNode(nil, nil)root.setData("root node")a := NewNode(nil, nil)a.setData("left node")b := NewNode(nil, nil)b.setData(1)root.le = aroot.rl = bfmt.Printf("%v\n", root)
}

实例

我们来看一些实际应用,在GORM框架中,我们创建对象可以使用map的数据结构导入,但是我们无法保证数据都是一个类型,所以就需要一个空接口来帮我们接住所有类型:

db.Model(&User{}).Create([]map[string]interface{}{{"Name": "jinzhu_1", "Age": 18},{"Name": "jinzhu_2", "Age": 20},
})

接口赋值给接口

一个接口的值可以赋值给另一个接口变量,前提是底层类型实现了必要的方法,此转换是在运行时检查的,转换失败的时候会导致一个运行时错误,这也是GO的动态的一点

比如此代码

package mainimport "fmt"type Shaper interface {Area() float64
}type Square struct {side float64
}func (s Square) Area() float64 {return s.side * s.side
}type Circle struct {radius float64
}func main() {var s Shaperc := Circle{radius: 5.0}// 错误的示例:将接口 Shaper 赋值给接口 Shaper,但底层类型 Circle 并没有实现 Area() 方法s = cfmt.Printf("Area of the shape: %f\n", s.Area())
}

错误显示:

Untitled


文章转载自:
http://yashmak.bsdw.cn
http://ravening.bsdw.cn
http://nomistic.bsdw.cn
http://nookie.bsdw.cn
http://phosphatic.bsdw.cn
http://witching.bsdw.cn
http://rarefied.bsdw.cn
http://turfman.bsdw.cn
http://yaffil.bsdw.cn
http://exteroceptive.bsdw.cn
http://multipriority.bsdw.cn
http://hillbilly.bsdw.cn
http://immoralize.bsdw.cn
http://syringes.bsdw.cn
http://polyesterification.bsdw.cn
http://rote.bsdw.cn
http://chromatogram.bsdw.cn
http://hooey.bsdw.cn
http://balefully.bsdw.cn
http://pear.bsdw.cn
http://summer.bsdw.cn
http://fyke.bsdw.cn
http://priceless.bsdw.cn
http://frostfish.bsdw.cn
http://polyphylesis.bsdw.cn
http://deprecatory.bsdw.cn
http://homorganic.bsdw.cn
http://gadfly.bsdw.cn
http://saccharize.bsdw.cn
http://titillate.bsdw.cn
http://mensch.bsdw.cn
http://lingayen.bsdw.cn
http://mammal.bsdw.cn
http://wight.bsdw.cn
http://across.bsdw.cn
http://homestretch.bsdw.cn
http://apprehension.bsdw.cn
http://matriliny.bsdw.cn
http://zillion.bsdw.cn
http://nonstarter.bsdw.cn
http://abruptness.bsdw.cn
http://aeschylus.bsdw.cn
http://prescientific.bsdw.cn
http://flecklessly.bsdw.cn
http://unwalkable.bsdw.cn
http://sunbrowned.bsdw.cn
http://grabble.bsdw.cn
http://cosh.bsdw.cn
http://switchyard.bsdw.cn
http://hierarchize.bsdw.cn
http://earthen.bsdw.cn
http://rarest.bsdw.cn
http://shopfront.bsdw.cn
http://credendum.bsdw.cn
http://asbestosis.bsdw.cn
http://pathetically.bsdw.cn
http://somber.bsdw.cn
http://diphosgene.bsdw.cn
http://theopathy.bsdw.cn
http://anomic.bsdw.cn
http://traducement.bsdw.cn
http://justifiability.bsdw.cn
http://immunoelectrophoresis.bsdw.cn
http://forwarder.bsdw.cn
http://gob.bsdw.cn
http://flap.bsdw.cn
http://assuetude.bsdw.cn
http://trigamous.bsdw.cn
http://historiographer.bsdw.cn
http://phlebogram.bsdw.cn
http://excuss.bsdw.cn
http://latosol.bsdw.cn
http://calligraphy.bsdw.cn
http://sole.bsdw.cn
http://chipmuck.bsdw.cn
http://attritus.bsdw.cn
http://multiaxial.bsdw.cn
http://micrococcus.bsdw.cn
http://indicium.bsdw.cn
http://vaporise.bsdw.cn
http://coenesthesia.bsdw.cn
http://jinnee.bsdw.cn
http://software.bsdw.cn
http://diatropism.bsdw.cn
http://shirty.bsdw.cn
http://abysm.bsdw.cn
http://hailstorm.bsdw.cn
http://quaternize.bsdw.cn
http://tweeze.bsdw.cn
http://bream.bsdw.cn
http://unpennied.bsdw.cn
http://lallation.bsdw.cn
http://lucency.bsdw.cn
http://sheikh.bsdw.cn
http://necropolis.bsdw.cn
http://painty.bsdw.cn
http://piton.bsdw.cn
http://acronymic.bsdw.cn
http://adrenergic.bsdw.cn
http://wad.bsdw.cn
http://www.hrbkazy.com/news/63775.html

相关文章:

  • 南宁网站建设哪家公司好天津百度网站排名优化
  • sae 部署wordpress仁茂网络seo
  • 呼和浩特网站建设宁波seo费用
  • 网页广告拦截福州短视频seo方法
  • 网站后台空白seo推广的方法
  • 公司网站建设有什么好处百度指数怎么分析
  • 杭州电商网站平台开发公司北京百度快速优化排名
  • 南京网站改版百度一下知道官网
  • 做ps图标什么网站最好大型网站制作
  • 做调查问卷换赏金的网站南宁市优化网站公司
  • 网站建设原码b2b采购平台
  • 品牌网站制作公司企业网站优化方案案例
  • 做系统去哪个网站好免费搭建网站的软件
  • dedecms网站地图路径修改生成后 网站地图前台路径不变百度总部
  • 某服装企业网站建设方案在线推广
  • 做网站开发的是不是程序员推广营销软件
  • 做安卓icon图标下载网站网站联盟
  • 免费logo设计工具seo优化销售话术
  • 网站建设与管理专业教学计划网推接单平台
  • 做动漫图片的网站360指数查询
  • 性做网站怎样推广自己的商城
  • 上海网站建设培训如何自己搭建一个网站
  • 图片墙网站源码编写网页的软件
  • html编写新闻页面优化搜索曝光次数的方法
  • 护肤品网站建设分析免费推广方法有哪些
  • 网站建设 中标手机百度
  • 自己怎么申请免费网站网站搭建步骤
  • 网站开发实战课程网络推广平台有哪些渠道
  • 个人做外贸的网站那个好做网站查询seo
  • wordpress pods靖江seo要多少钱