GO语言笔记--接口

1.接口interface

1)接口是一个或多个方法签名的集合

2)只要某个类型拥有该接口的所有方法签名,即算实现该接口无需显示声明实现了哪个接口,这称为Structural Typing

3)接口只有方法声明,没有实现,没有数据字段

4)接口可以匿名嵌入其他接口,或嵌入到结构中

5)将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,既无法修改复制品的状态,也无法获取指针

6)只有当接口存储的类型和对象为nil时,接口才等于nil

7)接口调用不会做receiver的自动转换

8)接口统一支持匿名自动方法

9)接口也可以实现类似OOP中的多态

10)空接口可以作为任何类型数据的容器

11)接口是由使用者定义得

 

2.类型断言

1)通过类型断言的ok pattern可以判断接口中的数据类型

2)使用tupe switch 则可针对空接口进行比较全面的类型判断

3.接口转换

可以将拥有超集的接口转换为子集的接口

实例,使用者定义接口

创建一个retiever目录,里面包含main.go 以及csdn/csdnRetiever.go两个文件

main.go代码,这里面使用到了定义的csdn这个包调用接口Retiever的Get方法:

package main


import (
    "fmt"
    "my-code/test-code/retiever/csdn"
)


type Retiever interface {
    Get(url string) string
}


func download(r Retiever) string {
    return r.Get("www.csdn.com")
}


func main() {
    var r Retiever
    r = csdn.Retiever{"hello www.csdn.com"}
    fmt.Println(download(r))
}

csdn/csdnRetiever.go代码中包含接口定义:

package csdn


type Retiever struct {
    Contents string
}


func (r Retiever) Get(url string) string {
    return r.Contents
}

上述代码传入一个url字符串并直接return
输出:
API server listening at: 127.0.0.1:34276
hello www.csdn.com

实例,访问百度

创建一个retiever目录,里面包含main.go 以及baidu/baidu.go两个文件

main.go代码,这里面使用到了定义的baidu这个包调用接口Retiever的Get方法:

package main


import (
    "fmt"
    "my-code/test-code/retiever/baidu"
)


type Retiever interface {
    Get(url string) string
}


func download(r Retiever) string {
    return r.Get("http://www.baidu.com")
}


func main() {
    var r Retiever
    r = baidu.Retiever{}
    fmt.Println(download(r))
}

baidu/baidu.go代码直接调用内置http接口访问百度:

package baidu


import (
    "net/http"
    "net/http/httputil"
    "time"
)


type Retiever struct {
    UserAgent string
    TimeOut   time.Duration
}


func (r Retiever) Get(url string) string {
    resp, err := http.Get(url)
    if err != nil {
        panic(err)
    }
    result, err := httputil.DumpResponse(resp, true)
    resp.Body.Close()
    if err != nil {
        panic(err)
    }
    return string(result)
}

上述实例运行结果是获取到了百度首页的html源码

4.查看接口内部元素

接口内部究竟是什么内容呢,将上述main.go代码修改如下打印出来查看:

func main() {
    var r Retiever
    r = baidu.Retiever{}
    //fmt.Println(download(r))
    fmt.Printf("%T\n%v\n", r, r)
}
运行结果如下:
API server listening at: 127.0.0.1:18265
baidu.Retiever
{ 0s}

上述打印看出%T打印的内容是baidu.Retiever这是接口名称,%v的内容是{ 0s},这是因为里面两个元素UserAgent未赋值因此是个空格,TimeOut未赋值所以默认0秒。为了更清晰的看出效果,下面将上述元素赋值查看:

package main


import (
    "fmt"
    "my-code/retiever/baidu"
    "time"
)


type Retiever interface {
    Get(url string) string
}


func download(r Retiever) string {
    return r.Get("http://www.baidu.com")
}


func main() {
    var r Retiever
    r = baidu.Retiever{
        UserAgent: "Mozilla/5.0",
        TimeOut:   time.Minute,
    }
    //fmt.Println(download(r))
    fmt.Printf("%T\n%v\n", r, r)
}

运行效果如下:
API server listening at: 127.0.0.1:16843
baidu.Retiever
{Mozilla/5.0 1m0s}

可以明显看出被赋值了

5.指针类型

如果接口类型修改为指针类型呢,代码如下:

baidu/baidu.go

package baidu


import (
    "net/http"
    "net/http/httputil"
    "time"
)


type Retiever struct {
    UserAgent string
    TimeOut   time.Duration
}


func (r *Retiever) Get(url string) string {
    resp, err := http.Get(url)
    if err != nil {
        panic(err)
    }
    result, err := httputil.DumpResponse(resp, true)
    resp.Body.Close()
    if err != nil {
        panic(err)
    }
    return string(result)
}

main.go源码不变:

package main


import (
    "fmt"
    "my-code/retiever/baidu"
    "time"
)


type Retiever interface {
    Get(url string) string
}


func download(r Retiever) string {
    return r.Get("http://www.baidu.com")
}


func main() {
    var r Retiever
    r = baidu.Retiever{
        UserAgent: "Mozilla/5.0",
        TimeOut:   time.Minute,
    }
    //fmt.Println(download(r))
    fmt.Printf("%T\n%v\n", r, r)
}

那么上述就会出错,执行报错如下:

# my-code/retiever

.\main.go:19:4: cannot use baidu.Retiever literal (type baidu.Retiever) as type Retiever in assignment:

baidu.Retiever does not implement Retiever (Get method has pointer receiver)

exit status 2

Process exiting with code: 1

此时就要修改为取地址了:

主函数修改如下:

func main() {
    var r Retiever
    r = &baidu.Retiever{
        UserAgent: "Mozilla/5.0",
        TimeOut:   time.Minute,
    }
    //fmt.Println(download(r))
    fmt.Printf("%T\n%v\n", r, r)
}

这样执行就不会出错了。

Type assertion
通过指针类型获取内部元素:
val := r.(*baidu.Retiever)
fmt.Println(val.TimeOut)
这样就可以取得具体元素了。
 

6.接口的组合

baidu/baidu.go提供Retiever接口:

package baidu


type Retiever struct {
    Contents string
}


func (r *Retiever) Post(url string, form map[string]string) string {
    r.Contents = form["contents"]
    return "ok"
}


func (r *Retiever) Get(url string) string {
    return r.Contents
}

 main.go代码这里面使用Poster和Retiever两个接口组合成一个RetieverPoster接口

package main


import (
    "fmt"
    "my-code/retiever/baidu"
)


type Retiever interface {
    Get(url string) string
}


type Poster interface {
    Post(url string, form map[string]string) string
}


const url = "http://www.baidu.com"


func download(r Retiever) string {
    return r.Get(url)
}


func post(poster Poster) {
    poster.Post(url,
        map[string]string{
            "name":   "baidu",
            "course": "golang",
        })
}


type RetieverPoster interface {
    Retiever
    Poster
}


func session(s RetieverPoster) string {
    s.Post(url, map[string]string{
        "contents": "hello baidu",
    })
    return s.Get(url)
}


func main() {
    retriever := baidu.Retiever{"hello http://www.baidu.com"}
    fmt.Println(session(&retriever))
}
执行效果如下:
API server listening at: 127.0.0.1:41871
hello baidu

虽然传入的是"hello http://www.baidu.com"但是输出的却是"hello baidu"这是因为在session方法里面修改了内容导致的。

7.GO语言常用系统接口

Stringer接口,在fmt/print.go内:

type Stringer interface {

    String() string

}

应用:在baidu包内实现一个String(),代码如下:

baidu/baidu.go

package baidu


import "fmt"


type Retiever struct {
    Contents string
}


func (r *Retiever) String() string {
    return fmt.Sprintf(
        "Retriver:{Contents=%s}", r.Contents)
}
func (r *Retiever) Post(url string, form map[string]string) string {
    r.Contents = form["contents"]
    return "ok"
}


func (r *Retiever) Get(url string) string {
    return r.Contents
}

main.go

package main


import (
    "fmt"
    "my-code/retiever/baidu"
)


type Retiever interface {
    Get(url string) string
}


func main() {
    r := &baidu.Retiever{
        Contents: "hello word",
    }
    fmt.Printf("%T\n%v\n", r, r)
}

输出:
API server listening at: 127.0.0.1:39863
*baidu.Retiever
Retriver:{Contents=hello word}

此外还有两个接口在io.go包内,分别是Reader和Writer

type Reader interface {

    Read(p []byte) (n int, err error)

}

type Writer interface {

    Write(p []byte) (n int, err error)

}

实例:

package main


import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
)


func printFile(name string) {
    file, err := os.Open(name)
    if err != nil {
        panic(err)
    }
    testIoReader(file)
}


func testIoReader(reader io.Reader) {
    scanner := bufio.NewScanner(reader)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}


func main() {
    printFile("ioTest.go")
    fmt.Println("##############print string#################")
    s := `abc"d"
    beijing
    nihao
    hello`
    testIoReader(strings.NewReader(s))
}

可以打印文件内容或者字符串里面的内容。

小结:

1.接口变量里面有什么
1)接口变量自带指针
2)接口变量同样采用值传递,几乎不需要使用接口的指针
3)指针接收者实现只能以指针方式使用;值接受者都可
 

2.查看接口变量

1)表示任何类型:interface{}

2)Type Assertion

3)Type Switch

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
R语言实战笔记第九章介绍了方差分析的内容。方差分析是一种用于比较两个或多个组之间差异的统计方法。在R语言中,可以使用lm函数进行方差分析的回归拟合。lm函数的基本用法是: myfit <- lm(I(Y^(a))~x I(x^2) I(log(x)) var ... [-1],data=dataframe 其中,Y代表因变量,x代表自变量,a代表指数,var代表其他可能对模型有影响的变量。lm函数可以拟合回归模型并提供相关分析结果。 在方差分析中,还需要进行数据诊断,以确保模型的可靠性。其中几个重要的诊断包括异常观测值、离群点和高杠杆值点。异常观测值对于回归分析来说非常重要,可以通过Q-Q图和outlierTest函数来检测。离群点在Q-Q图中表示落在置信区间之外的点,需要删除后重新拟合并再次进行显著性检验。高杠杆值点是指在自变量因子空间中的离群点,可以通过帽子统计量来识别。一般来说,帽子统计量高于均值的2到3倍即可标记为高杠杆值点。 此外,方差分析还需要关注正态性。可以使用car包的qqplot函数绘制Q-Q图,并通过线的位置来判断数据是否服从正态分布。落在置信区间内为优,落在置信区间之外为异常点,需要进行处理。还可以通过绘制学生化残差的直方图和密度图来评估正态性。 综上所述,R语言实战第九章介绍了方差分析及其相关的数据诊断方法,包括异常观测值、离群点、高杠杆值点和正态性检验。这些方法可以用于分析数据的可靠性和模型的适应性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [R语言实战笔记--第八章 OLS回归分析](https://blog.csdn.net/gdyflxw/article/details/53870535)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值