这两天迷上了SEO。真心看不起百度的竞价排名,但作为一个商业网站,赚钱是一件无可厚非的事情。只做活雷锋,没有大金主是做不长的。做完功课后,发现百度和google的SEO策略又不相同,几乎是无法通用。百度目前占据着国内搜索市场70%的市场份额,虽然不齿百度的龌龊之举,但也只能沉下心来好好琢磨琢磨百度的SEO策略。以前没有接触过SEO,不懂这里面的水。这两天着了迷想好好研究研究SEO,才发现原来内容是否原创,网页类型(静态/动态),关键字覆盖率,robots是否满足要求,外链质量,网站结构都会影响到最终的排名。当然这里说的都是明面上的技术操作,没提那些个灰色产业。既然称之为灰色产业了,没有老司机带着,也很难明白是怎么运作的。问了一些买过SEO优化的朋友得知,有的SEO优化立竿见影,基本一周后就能冲到前10位,但不续费后,马上下来(肯定有猫腻,但外行人还就是看不懂)。有的SEO会承诺保持多长时间,结果可想而知,这个排名会逐渐逐渐下降。以前感觉写代码是个技术活,最近一段时间越来越发现,写代码真心是个简单的活,这些个说不清道不明,又能挣钱的才是技术活。这几天有时间了,再看看SEO,看能不能把自己的博客也冲到前10名去。

但在冲前十之前,先坚持把这个系列写完了。

<朝鲜三胖哥> 那一节,聊了一嘴,从普通类型转换到interface{}是隐式转换。这节就说一下interface{}这个类型吧,要不总感觉内容少一块。反正也是入门级的书,聊嘛不是聊呀。我准备写完了以后,出一个视频系列,那会就改叫<golang脱口秀>。如果你有好的段子,好的想法或者要推广嘛东西,欢迎发邮件给我(ztao8607@gmail.com),现在有一个影视公司已经下定了,其他人抓紧哦。

Golang中的interface{}有两层含义,一层是单纯的interface{},可以理解成Java的Object基类。因此所有的数据类型都可以转化成interface{}。另外一层含义,就是接口类。这个接口类和Java的接口类又几乎差不多,都是只声明一些方法,而不具体实现。其实第一层里面的interface{}可以理解成特殊的接口类,这个接口类里面没有声明任何方法。所以两层含义可以统一成一个事物。

如果直接把Java里面的接口含义拿过来,这就没有意思了,也就不用写Golang里面的接口类了。Golang的接口和Java的接口说到底本质相同,但模样千秋。下面来看Golang中如何声明一个接口:

type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}

在声明struct时候,是type name struct。这里声明接口,是用type name interface,所以不用混淆了。在struct里面,都是各个成员属性,而在interface里面,就都是各个成员函数。从这点来看,Golang和Java的interface声明区别不大,大的区别在如何使用上面,Golang的使用要比Java灵活太多了。用事实来说话,看下面:

type Shape interface {
area() float64
} func getArea(shape Shape) float64 {
return shape.area()
}

声明了一个Shape的interface,里面有一个成员函数,是area,返回一个float64。而getArea只接受Shape接口类型。好,该上实现类了。

type Circle struct {
x,y,radius float64
}
func(circle Circle) area() float64 {
return math.Pi * circle.radius * circle.radius
}

现在Circle类就实现了刚才Shape的接口。不信,自己敲个代码,验证一下:

circle := Circle{x:0,y:0,radius:5}
fmt.Printf("Circle area: %f\n",getArea(circle))

嘿,一准儿能给你输出结果。

如果只有一个实现类,那就体现不出接口的优势了。再上一个实现类:

type Rectangle struct {
width, height float64
}
func(rect Rectangle) area() float64 {
return rect.width * rect.height
}
rectangle := Rectangle {width:10, height:5}
fmt.Printf("Rectangle area: %f\n",getArea(rectangle))

瞅瞅,又不一样了吧。现在Rectangle和Circle都实现了Shape接口类。怎么实现的?如果你是从Java转过来的,一定会默认去找extend关键字,瞅准了,上面可没有extend关键字。

实现的秘密就在于Rectangle和Circle两个类都有area() float64这个函数。所以在Golang当中,如何实现一个接口类?那就是把接口类中的函数都实现了,就成。

无论接口类中定义了几个函数,都实现了。如果用不着,那就写个函数声明,里面加上空实现就可以。照这个逻辑,一个实现类理论上岂不是能实现无限个接口? 恩,是的,you are right!是这样的!

如果一个项目中,代码太多了,或者交接了好几把手,等你分析代码的时候,你都不知道这个类实现了多少个接口。正所谓有利有弊,Golang中接口的灵活性可以大大减少代码量,减少耦合性。但也反过来降低了可读性,举个例子,如果程序出了bug,而这个bug恰恰出现在一个接口函数中,看代码的时候,你都不知道是哪个实现类出的问题。别说使用go的debug工具,在线上很少会有通过debug打断点进行调试的机会,一来线上环境这么容易进行debug,就说明太不安全了。理论上生产环境中的代码都不应该包含debug信息。二来,有些问题只有在满足一定条件,例如大流量,高并发,某些特殊请求下才能复现,贸然使用debug,已经破坏复现环境了,半天都找不到问题。所以建议在写代码的时候,一定要记得输出日志,最好能在关键节点输出尽可能的详细日志。

Golang中的接口基本使用方法就是这些,如果你有Java基础那么就没有学习难度了。如果没有,也没关系,多写几个代码也就差不多了。下面来看一下实际环境中经常使用到的接口:

type error interface {
Error() string
}

没错,是Error。在此之前,我们都没有考虑如果代码出错了怎么办?所以这个时候就补上这个漏洞。Golang没有try.. catch.. finally。所有的错误都是通过error来处理的,经典的代码如下:

err := xxxxxx
if err != nil {
....
}

基本就是这样,再高逼格的,就是把err在封装成各种类型。但基本都是这样一套处理方式。Golang也允许自己创建error信息,比如:

func Sqrt(value float64)(float64, error) {
if(value < 0){
return 0, errors.New("Math: negative number passed to Sqrt")
}
return math.Sqrt(value)
}

用户可以通过errors.New()来创建自带业务逻辑的错误信息。这方面就不多展开了,因为每个team都有自己的编码规范,对error的处理方式也千奇百怪,没法统一说明。但处理模式就上面那一套,所以最后来一个实际代码结束Error:

package main

import "errors"
import "fmt"
import "math" func Sqrt(value float64)(float64, error) {
if(value < 0){
return 0, errors.New("Math: negative number passed to Sqrt")
}
return math.Sqrt(value), nil
}
func main() {
result, err:= Sqrt(-1) if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
} result, err = Sqrt(9) if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
}
}

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan

SEO是件贼有意思的事情 golang入坑系列的更多相关文章

  1. 入坑第二式 golang入坑系列

    史前必读: 这是入坑系列的第二式,如果错过了第一式,可以去gitbook( https://andy-zhangtao.gitbooks.io/golang/content/ )点个回放,看个重播.因 ...

  2. 初生牛犊不怕虎 golang入坑系列

    读前必读,下面所有内容都是来自这里. 放到这里的目的,就是为了比对一下,哪里的读者多.平心而论,同样的Markdown,博客园排版真心X看,怎么瞅怎么X看.(X := '难' || X :='耐' | ...

  3. 维多利亚的秘密 golang入坑系列

    原文在gitbook,字字原创,版权没有,转载随意. 在写本文的前一天,2017维密在上海开始了. 为了纪念屌丝界的盛世,特为本节起名维多利亚的秘密.现在的社会,要想出名只有抓眼球.所以写份技术文章, ...

  4. 来自朝鲜的问候 golang入坑系列

    鸿渐于陆 本想着写满十八式,但按照目前的进度来看,是很难凑够十八式了.所以还是那句话,量力而行,适可而止.能写多少就写多少,我没法保证看完这本golang脱口秀,一定能成为golang大拿.但入了门, ...

  5. 脱掉Golang的第一层衣裳 golang入坑系列

    读前必读,博客园的文章并非最新,想看最新还是建议点击这里.博客园的文章是为了方便不能FQ的同学,同步而来的.不放在博客园,不是不支持国产,而是博客园的排版太难看了,太难看了,太难看了!而且还没有客户端 ...

  6. 邻里街坊 golang入坑系列

    如果要追新或者怀旧,就点击https://andy-zhangtao.gitbooks.io/golang/content/ . 博客园里面的文章基本和gitbook上面是保持同步的. 这几天看了几集 ...

  7. 乐呵乐呵得了 golang入坑系列

    开场就有料,今天返回去看了看以前的文章,轻松指数有点下降趋势.一琢磨,这不是我的风格呀.一反思,合着是这段时间,脑子里杂七杂八的杂事有点多,事情一多,就忘了快乐.古话说得好:愁也一天,乐也一天,只要还 ...

  8. 我们是80后 golang入坑系列

    现在这个系列,已经开始两极分化了. 点赞的认为风格轻松,看着不困.反之,就有人嫌写的罗里吧嗦,上纲上线.所以善意提醒,里面不只是技术语言,还有段子.专心看技术的,千万别点!别怪我没提醒!差点忘说,版权 ...

  9. 准备冲锋 golang入坑系列

    史前摘要: 本来想写读前必读,但连续几篇博文都写读前必读,感觉就没有了新意. 所以换成史前摘要,反正是一个意思. 此摘要的目的仍然是提醒点击而来的同学,本系列最新文章在这里.放到博客园的目的是为了方便 ...

随机推荐

  1. LeetCode 495. Teemo Attacking (提莫攻击)

    In LOL world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned ...

  2. JAVA提高九:集合体系

    在经过了前面的JDK6.0新特性的学习后,将进一步深入学习JDK,因为集合的重要性,因此从集合开始入手分析: 一.集合概况 Java是一种面向对象语言,如果我们要针对多个对象进行操作,那么首先必要将多 ...

  3. 忘记root密码,进入单用户模式修改密码

    进入单用户模式 rhel61.在系统数秒时,按下键,进入到系统引导菜单 中2.选择系统后 按“e”键 选择kernel后 按“e”键 后空格 1+回车 b:启动系统 进入到单用户模式 rhel71.在 ...

  4. JS框架设计读书笔记之-函数

    这次写一些函数 1.模拟Object.keys方法 Object.keys = Object.keys || function(obj){ var a = []; // a[0],a[1]...分别赋 ...

  5. 前端开发:H5直播起航

    前言 前不久抽空对目前比较火的视频直播,做了下研究与探索,了解其整体实现流程,以及探讨移动端HTML5直播可行性方案. 发现目前 WEB 上主流的视频直播方案有 HLS 和 RTMP,移动 WEB 端 ...

  6. 借助csv用PHP生成excel文件

    当你将xml文件改为csv后缀会发现原先的表格结构都变成用逗号隔开的一行一行数据,就像这样 编号,姓名,年龄 001,王宇,28 002,刘三,20 由此看来,如果能将PHP数据输出为这样的格式,然后 ...

  7. asp.net core webapi文件上传

    最近开发一个新项目,使用了asp.net core 2.0,采用webapi开发后台,postgresql为数据库.最先来的问题就是上传文件的问题. POST文件的一些坑 使用默认模板创建webapi ...

  8. Python中time和datetime模块的简单用法

    python中与时间相关的一个模块是time模块,datetime模块可以看为是time模块的高级封装. time模块中经常用到的有一下几个方法: time()用来获取时间戳,表示的结果为从1970年 ...

  9. vue 使用axios 跨域请求数据的问题

    axios默认是没有jsonp 跨域请求的方法的.一般来说流行的做法是将跨域放在后台来解决,也就是后台开发人员添加跨域头信息. 例如java中的 header,response.setHeader(& ...

  10. mysql查询锁表及解锁

    SHOW PROCESSLIST; KILL ; 锁表网上解释: 这牵涉到mysql的事务,简单通俗的话,就这样给你解释有一个任务序列控制sql语句的执行,第一次有select的语句查询表a,mysq ...