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

旧电脑做php网站服务器wordpress多个字体

旧电脑做php网站服务器,wordpress多个字体,个人简历网站模板下载,diy wordpress接口接口值警告#xff1a;一个包含空指针值的接口不是nil接口sort.Interface接口http.Handler接口类型断言类型分支接口值 接口值#xff0c;由两个部分组成#xff0c;一个具体的类型和那个类型的值。它们被称为接口的动态类型和动态值。对于像Go语言这种静态类型的语言一个包含空指针值的接口不是nil接口sort.Interface接口http.Handler接口类型断言类型分支接口值 接口值由两个部分组成一个具体的类型和那个类型的值。它们被称为接口的动态类型和动态值。对于像Go语言这种静态类型的语言类型是编译期的概念因此一个类型不是一个值。在我们的概念模型中一些提供每个类型信息的值被称为类型描述符比如类型的名称和方法。在一个接口值中类型部分代表与之相关类型的描述符。 var w io.Writer w os.Stdout w new(bytes.Buffer) w nil第一个语句定义了变量w: var w io.Writer变量总是被一个定义明确的值初始化即使接口类型也不例外。对于一个接口的零值就是它的类型和值的部分都是nil。 第二个语句将一个*os.File类型的值赋给变量w: w os.Stdout这个赋值过程调用了一个具体类型到接口类型的隐式转换这和显式的使用io.Writer(os.Stdout)是等价的。这类转换不管是显式的还是隐式的都会刻画出操作到的类型和值。这个接口值的动态类型被设为*os.File指针的类型描述符它的动态值持有os.Stdout的拷贝这是一个代表处理标准输出的os.File类型变量的指针。 调用一个包含*os.File类型指针的接口值的Write方法使得(*os.File).Write方法被调用。 效果和下面这个直接调用一样 os.Stdout.Write([]byte(hello)) // hello接口值可以使用和!来进行比较。两个接口值相等仅当它们都是nil值或者它们的动态类型相同并且动态值也根据这个动态类型的操作相等。因为接口值是可比较的所以它们可以用在map的键或者作为switch语句的操作数。 然而如果两个接口值的动态类型相同但是这个动态类型是不可比较的比如切片将它们进行比较就会失败并且panic 当我们处理错误或者调试的过程中得知接口值的动态类型是非常有帮助的。所以我们使用fmt包的%T动作: var w io.Writer fmt.Printf(%T\n, w) // nil w os.Stdout fmt.Printf(%T\n, w) // *os.File警告一个包含空指针值的接口不是nil接口 关键一个接口只有动态类型和动态值都是nil对其进行nil判断时才为true否则为false。 针对赋值的时候如果两者类型不同那么即使传入的值是nil但是被赋值(接口)的动态类型会被更改为传入的类型。 比如 const debug truefunc main() {var buf *bytes.Bufferif debug {buf new(bytes.Buffer) // enable collection of output}f(buf) // NOTE: subtly incorrect!if debug {// ...use buf...} }// If out is non-nil, output will be written to it. func f(out io.Writer) {// ...do something...if out ! nil {out.Write([]byte(done!\n))} }此时如果debugfalse那么调用函数f()时传入的类型是*bytes.Buffer与参数类型不一致那么此时out的动态类型就是*bytes.Buffer。根据前文所说接口的动态类型不为空那么此时out!nil就为true而不是预期的false了。 修改方式如下 var buf io.Writer此时调用f()方法时传入的类型与参数类型一致所以此时的out动态类型和动态值都是nil也就不会出现问题了。 sort.Interface接口 一个内置的排序算法需要知道三个东西序列的长度表示两个元素比较的结果一种交换两个元素的方式这就是sort.Interface的三个方法 package sorttype Interface interface {Len() intLess(i, j int) bool // i, j are indices of sequence elementsSwap(i, j int) }按照一种类型的某个值排序 type byArtist []*Track func (x byArtist) Len() int { return len(x) } func (x byArtist) Less(i, j int) bool { return x[i].Artist x[j].Artist } func (x byArtist) Swap(i, j int) { x[i], x[j] x[j], x[i] }sort.Sort(byArtist(tracks))对tracks进行逆向排序。然而我们不需要定义一个有颠倒Less方法的新类型byReverseArtist因为sort包中提供了Reverse函数将排序顺序转换成逆序。Z sort.Sort(sort.Reverse(byArtist(tracks)))sort包定义了一个不公开的struct类型reverse它嵌入了一个sort.Interface。reverse的Less方法调用了内嵌的sort.Interface值的Less方法但是通过交换索引的方式使排序结果变成逆序。 package sorttype reverse struct{ Interface } // that is, sort.Interfacefunc (r reverse) Less(i, j int) bool { return r.Interface.Less(j, i) }func Reverse(data Interface) Interface { return reverse{data} }对于我们需要的每个切片元素类型和每个排序函数我们需要定义一个新的sort.Interface实现。 Len和Swap方法对于所有的切片类型都有相同的定义。下个例子具体的类型customSort会将一个切片和函数结合使我们只需要写比较函数就可以定义一个新的排序。 type customSort struct {t []*Trackless func(x, y *Track) bool }func (x customSort) Len() int { return len(x.t) } func (x customSort) Less(i, j int) bool { return x.less(x.t[i], x.t[j]) } func (x customSort) Swap(i, j int) { x.t[i], x.t[j] x.t[j], x.t[i] }sort.Sort(customSort{tracks, func(x, y *Track) bool {if x.Title ! y.Title {return x.Title y.Title}if x.Year ! y.Year {return x.Year y.Year}if x.Length ! y.Length {return x.Length y.Length}return false }})sort包中的IsSorted函数帮我们做这样的检查。 values : []int{3, 1, 4, 1} fmt.Println(sort.IntsAreSorted(values)) // false //对ints排序 sort.Ints(values) fmt.Println(values) // [1 1 3 4] fmt.Println(sort.IntsAreSorted(values)) // true //对int切片排序 sort.Sort(sort.Reverse(sort.IntSlice(values))) fmt.Println(values) // [4 3 1 1] fmt.Println(sort.IntsAreSorted(values)) // falsehttp.Handler接口 package httptype Handler interface {ServeHTTP(w ResponseWriter, r *Request) }func ListenAndServe(address string, h Handler) errorListenAndServe函数需要一个例如“localhost:8000”的服务器地址和一个所有请求都可以分派的Handler接口实例。它会一直运行直到这个服务因为一个错误而失败或者启动失败它的返回值一定是一个非空的错误。 func main() {db : database{shoes: 50, socks: 5}log.Fatal(http.ListenAndServe(localhost:8000, db)) }type dollars float32func (d dollars) String() string {return fmt.Sprintf($%.2f, d) }type database map[string]dollarsfunc (db database) ServeHTTP(w http.ResponseWriter, req *http.Request) {for item, price : range db {fmt.Fprintf(w, %s%s, item, price)} }满足同一接口的不同类型是可替换的。 显然我们可以继续向ServeHTTP方法中添加case但在一个实际的应用中将每个case中的逻辑定义到一个分开的方法或函数中会很实用。net/http包提供了一个请求多路器ServeMux来简化URL和handlers的联系。一个ServeMux将一批http.Handler聚集到一个单一的http.Handler中。 func main3() {db : database{shoes: 50, socks: 5}mux : http.NewServeMux()mux.Handle(/list, http.HandlerFunc(db.list))mux.Handle(price, http.HandlerFunc(db.price))log.Fatal(http.ListenAndServe(localhost:8000, mux)) }func (db database) list(w http.ResponseWriter, req *http.Request) {for item, price : range db {fmt.Fprintf(w, %s:%s\n, item, price)} }func (db database) price(w http.ResponseWriter, req *http.Request) {item : req.URL.Query().Get(item)price, ok : db[item]if !ok {w.WriteHeader(http.StatusNotFound)fmt.Fprintf(w, no such item:%q\n, item)return}fmt.Fprintf(w, %s\n, price) }语句http.HandlerFunc(db.list)是一个转换而非一个函数调用因为http.HandlerFunc是一个类型。它有如下的定义 package httptype HandlerFunc func(w ResponseWriter, r *Request)func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {f(w, r) }ServeHTTP方法的行为是调用了它的函数本身。因此HandlerFunc是一个让函数值满足一个接口的适配器这里函数和这个接口仅有的方法有相同的函数签名。 net/http包提供了一个全局的ServeMux实例DefaultServerMux和包级别的http.Handle和http.HandleFunc函数。现在为了使用DefaultServeMux作为服务器的主handler我们不需要将它传给ListenAndServe函数nil值就可以工作。相当于就是如果我们不给ListenAndServe函数传入特定的ServerMux或者直接调用http.HandlerFunc函数的话就会去使用特定的全局ServerMux实例。 类型断言 类型断言是一个使用在接口值上的操作。语法上它看起来像x.(T)被称为断言类型这里x表示一个接口的类型和T表示一个类型。一个类型断言检查它操作对象的动态类型是否和断言的类型匹配。类型断言检查x的动态值类型是否和T相同返回结果的真实值是x的动态值类型改为T。 这里有两种可能 第一种如果断言的类型T是一个具体类型然后类型断言检查x的动态类型是否和T相同。换句话说具体类型的类型断言从它的操作对象中获得具体的值。如果检查失败接下来这个操作会抛出panic。例如 var w io.Writer w os.Stdout f : w.(*os.File) // success: f os.Stdout c : w.(*bytes.Buffer) // panic: interface holds *os.File, not *bytes.Buffer第二种如果断言的类型T是一个接口类型然后类型断言检查是否x的动态类型满足T。 对一个接口类型的类型断言改变了类型的表述方式改变了可以获取的方法集合通常更大但是它保留了接口值内部的动态类型和值的部分。在下面的第一个类型断言后w和rw都持有os.Stdout因此它们都有一个动态类型*os.File但是变量w是一个io.Writer类型只对外公开了文件的Write方法而rw变量还公开了它的Read方法。 var w io.Writer w os.Stdout rw : w.(io.ReadWriter) // success: *os.File has both Read and Write w new(ByteCounter) rw w.(io.ReadWriter) // panic: *ByteCounter has no Read method经常地对一个接口值的动态类型我们是不确定的并且我们更愿意去检验它是否是一些特定的类型。如果类型断言出现在一个预期有两个结果的赋值操作中例如如下的定义这个操作不会在失败的时候发生panic但是替代地返回一个额外的第二个结果这个结果是一个标识成功与否的布尔值 var w io.Writer os.Stdout f, ok : w.(*os.File) // success: ok, f os.Stdout b, ok : w.(*bytes.Buffer) // failure: !ok, b nil第二个结果通常赋值给一个命名为ok的变量。如果这个操作失败了那么ok就是false值第一个结果等于被断言类型的零值在这个例子中就是一个nil的*bytes.Buffer类型。 这个ok结果经常立即用于决定程序下面做什么。if语句的扩展格式让这个变的很简洁 if f, ok : w.(*os.File); ok {// ...use f... }例子 func writeString(w io.Writer, s string) (n int, err error) {type stringWriter interface {WriteString(string) (n int, err error)}if sw, ok : w.(stringWriter); ok {return sw.WriteString(s) // avoid a copy}return w.Write([]byte(s)) // allocate temporary copy }满足以下接口即可调用 interface {io.WriterWriteString(s string) (n int, err error) }类型分支 接口被以两种不同的方式使用。 在第一个方式中以io.Readerio.Writerfmt.Stringersort.Interfacehttp.Handler和error为典型一个接口的方法表达了实现这个接口的具体类型间的相似性但是隐藏了代码的细节和这些具体类型本身的操作。重点在于方法上而不是具体的类型上。 第二个方式是利用一个接口值可以持有各种具体类型值的能力将这个接口认为是这些类型的联合。类型断言用来动态地区别这些类型使得对每一种情况都不一样。在这个方式中重点在于具体的类型满足这个接口而不在于接口的方法如果它确实有一些的话并且没有任何的信息隐藏。我们将以这种方式使用的接口描述为discriminated unions可辨识联合。 一个类型分支像普通的switch语句一样它的运算对象是x.(type)——它使用了关键词字面量type——并且每个case有一到多个类型。一个类型分支基于这个接口值的动态类型使一个多路分支有效。 switch x.(type) { case nil: // ... case int, uint: // ... case bool: // ... case string: // ... default: // ... }常见用法 将提取的值绑定到一个在每个case范围内都有效的新变量。 switch x : x.(type) { /* ... */ }也就是说当匹配到具体某个单一类型case的时候变量x和这个case的类型相同 例如 func sqlQuote(x interface{}) string {switch x : x.(type) {case nil:return NULLcase int, uint:return fmt.Sprintf(%d, x) // x has type interface{} here.case bool:if x {return TRUE}return FALSEcase string:return sqlQuoteString(x) // (not shown)default:panic(fmt.Sprintf(unexpected type %T: %v, x, x))} }变量x在bool的case中是bool类型在string的case中是string类型。
http://www.w-s-a.com/news/903528/

相关文章:

  • 杭州租房网站建设设计网站架构
  • 安徽做网站公司哪家好建设网站需要什么内容
  • 哪些网络公司可以做机票预订网站网站新闻后台怎么做
  • 微网站 域名企业网站怎么做推广
  • 兴安盟住房和城乡建设部网站在国外做网站
  • 南雄市建设局网站搜索关键词的方法
  • 网站建设维护工作经验深圳定制展会
  • 新闻类网站备案WordPress评论昵称显示错误
  • 如何建立一个个人网站自己做一个购物网站
  • 吴忠网站建设公司中国建筑股份有限公司 官网
  • 深圳电商网站开发公司page list wordpress
  • 长安外贸网站建设顺德区网站设计建设企业
  • 临沂市建设局网站简介专业建设网站开发
  • 肇庆网站制作设计中国企业500强招聘
  • 苏州厂房装修宁波seo网络推广外包报价
  • 文山知名网站建设惠州哪家做网站好
  • 物流网站风格网站登录密码保存在哪里设置
  • 免费网站怎么建立icodepython基础教程
  • 无障碍网站建设方案wordpress 任务管理系统
  • iis5.1发布网站中小企业网络营销存在的问题研究论文
  • 阳泉软件定制网站建设网站可以做多语言的吗
  • 建设网站的目的及功能定位主要包括哪些内容百度关键词优化
  • 开一个小程序要多少钱宁波seo网络推广外包报价
  • 网站备案最新备案号电子商务网站建设的规章制度
  • wordpress制作单页网站导航页面鞍山信息港招聘信息
  • 屏蔽ip地址访问网站自己做衣服的网站
  • 网站建设 域名业务 邮箱哪里有网站建设中心
  • 免费网站赚钱重庆建设摩托车股份有限公司
  • 合肥水运建设工程监理网站自己买服务器能在wordpress建网站
  • wordpress积分商城主题整站seo排名要多少钱