在Go中实现接口

My project is organized as follows

github.com/achanda/poke
├── cmd
│   └── poke.go
├── scanner.go
├── txt_scanner.go
└── types.go

The files are as follows

# cat scanner.go
package poke

type Scanner interface {
    Scan() *ScanResult
}

# cat txt_scanner.go
package poke

type txtScanner struct {
    txt string
}

func newTxtScanner(host string) Scanner {
    return txtScanner{txt}
}

func (tcpcs txtScanner) Scan() *ScanResult {
    // do stuff
    return &result
}

Now I am trying to call this in my main package (in poke.go) like this

package main

import "github.com/achanda/poke"

func main() {
    var sr poke.Scanner
    sr = poke.txtScanner{txt}
    sr.Scan()
}

This fails to run with

# command-line-arguments
./poke.go:111: cannot refer to unexported name poke.txtScanner
./poke.go:111: undefined: portscan.txtScanner

What am I doing wrong?

you need to access type or field outside package, so you should export them using first letter upper case:

first you should define your txtScanner and txt string with first upper case letter, otherwise you will see this error too:

.\poke.go:8: implicit assignment of unexported field 'txt' in poke.TxtScanner literal

like this:

type TxtScanner struct {
    Txt string
}

also see newTxtScanner(host string) function in this working sample codes:
poke.go:

package main

import "github.com/achanda/poke"

func main() {
    s := "test"
    var sr poke.Scanner
    sr = poke.TxtScanner{s}
    sr.Scan()
}

txt_scanner.go:

package poke

type TxtScanner struct {
    Txt string
}

func newTxtScanner(host string) Scanner {
    return TxtScanner{host}
}

func (tcpcs TxtScanner) Scan() *ScanResult {
    // do stuff
    result := ScanResult{}
    return &result
}

types.go:

package poke

type ScanResult struct {
}

scanner.go:

package poke

type Scanner interface {
    Scan() *ScanResult
}