前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬虫遇到了点问题

爬虫遇到了点问题

作者头像
我的小碗汤
发布2018-09-30 10:30:59
1K0
发布2018-09-30 10:30:59
举报
文章被收录于专栏:我的小碗汤我的小碗汤

golang爬珍爱网代码优化后,运行报了如下的错,找了半小时才找到原因,在此记录一下。

代码是这样的:

有一个interface类型的Parser:

代码语言:javascript
复制
type Parser interface {
   Parser(contents []byte, url string) ParserResult
   Serialize() (funcName string, args interface{})
}

有一个struct类型的FuncParser:

代码语言:javascript
复制
type FuncParser struct {
   parser ParserFunc
   funcName string
}

FuncParser 实现了Parser 接口:

代码语言:javascript
复制
func (f *FuncParser) Parser(contents []byte, url string) ParserResult {
   return f.Parser(contents, url)
}

func (f *FuncParser) Serialize() (funcName string, args interface{}) {
   return f.funcName, nil
}

抛开爬虫代码整体的复杂度,将代码简化到如下这样:

代码语言:javascript
复制
type ParserFunc func(url string) string

type FuncParser struct {
    parser ParserFunc
}

func (f *FuncParser) Parser(url string) string {
    return f.Parser(url)
}

func main() {

    funcParse := FuncParser{
        func(url string) string {
            return url
        },
    }

    funcParse.Parser("http://www.zhenai.com/zhenghun")
}

运行代码后同样会报错:

代码语言:javascript
复制
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

runtime stack:
runtime.throw(0x467297, 0xe)
    D:/Program Files/Go/go103/src/runtime/panic.go:616 +0x88
runtime.newstack()
    D:/Program Files/Go/go103/src/runtime/stack.go:1054 +0x72d
runtime.morestack()
    D:/Program Files/Go/go103/src/runtime/asm_amd64.s:480 +0x91

这个示例就很明显了,FuncParser的Parser方法里形成了递归调用(自己调自己),递归调用自身导致栈溢出,导致报错。应该改成这样:(小写的parser)

实际上goland开发工具里已经提示了Recursive Call


一不小心就会写出这种代码,再看如下代码:

代码语言:javascript
复制
package main

import (
    "fmt"
)

type Str string

func (s Str) String() string {
    return fmt.Sprintf("Str: %s", s)
}

func main() {
    var s Str = "hi"
    fmt.Println(s)
}

同样报错:

You are implementing Str.String in terms of itself. return fmt.Sprintf("Str: %s", s) will call s.String(), resulting in infinite recursion. Convert s to string first.

This is working as intended, you are using the %s verb to call Str's String method, which uses fmt.Sprint to call Str's String method, and so on.

正常代码应该如下:

实际上,goland开发工具里也会警告该问题的:

看来平时编写代码,警告还是得注意的。

项目代码见:https://github.com/ll837448792/crawler

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 进击云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档