I am learning Go using "The Go Programming Language" book. First chapter introduced os.Open
module for reading files. I tried opening a go file like below.
f, err = os.Open("helloworld.go")
I got following error:
# command-line-arguments
.\helloworld.go:6:6: main redeclared in this block
previous declaration at .\dup2.go:10:6
I want to understand why go behaved as if it's trying to compile the file instead of reading like other languages ( Python, Java or C) do.
What is the correct way of opening a file?
The error you got indicate that you have 2 main()
function in the same package.
A package can have many files. When you have multiple .go
files in the same directory that you run go build
command in, the compiler will build the main
package. In this case, it detected duplicated main()
function hence the build failed.
What you want to do is specify which file you want to build:
go build helloworld.go
With the file specified, go build
will only build with the file(s) you have listed.
For more information on go build
you can refer to Golang Documentation .
Though you shouldn't do it but technically you can read a '.go' file with main() from another.go file. Your case is failing as you are building a package having multiple files defining main.
Again clarifying, it is discouraged to have multiple files with main in the same package, and it will fail when you build the package. This is so, as there should be just one entry point (main() function) in the package.
Coming to technicality, you can read a go file from another in same package, but in this case you need to build just the file (not the whole package). Alternately you can issue go run
$ cat main1.go
package main
import "fmt"
func main() {
fmt.Println("Hello")
}
$
$ cat readinfolder.go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
filehandle, err := os.Open("main1.go")
if err != nil {
panic(err)
}
defer filehandle.Close()
scanner := bufio.NewScanner(filehandle)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
$
$
$ go build readinfolder.go
$ ./readinfolder
package main
import "fmt"
func main() {
fmt.Println("Hello")
}
$
I'll show you how I've read files into a Directory.
1: You should make the package and import tools:
2: Make new structs for Files and Directories.
3: Make some functions to read new files.
4: Execute your tasks in main function
5: Use ioutil.ReadFile function to read some file
Directory tree
.
|____main.go
|____files
| |____example2.txt
| |____example1.txt
Example code:
package main
import (
"fmt"
"io/ioutil"
"log"
)
// Define Directory struct
type Directory struct {
Path string
Files []File
}
// Define File struct
type File struct {
Name string
}
// Function to return path
func (this Directory) getPath() string {
return this.Path
}
// Function to set a path
func (this Directory) setPath(path string) string {
this.Path = path
return this.Path
}
// Function to get fies into a directory
func (this Directory) getFiles(path string) []File {
directory, err := ioutil.ReadDir(path)
if err != nil {
log.Fatal(err)
}
for _, f := range directory {
this.Files = append(this.Files, File{Name: f.Name()})
}
return this.Files
}
//Main function
func main() {
// Set variables
dir := new(Directory)
path := dir.setPath("/home/your_user/your_project_folder/files/")
files := dir.getFiles(path)
firstFiles := dir.getFiles(path)[0].Name
//Read File
f, err := ioutil.ReadFile("/home/your_user/your_project_folder/files/" + firstFiles)
if err != nil {
log.Fatal(err)
}
// Print results
fmt.Println(files)
fmt.Println(firstFiles)
fmt.Println(string(f))
}
output:
[{example1.txt} {example2.txt}]
example1.txt
some text in file!
Finally: You should do go build
, to build the project as a binary.
I hope this example may help you to understand better how golang works
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.