For Go, ioutil.ReadAll / ioutil.ReadFile / ioutil.ReadDir deprecated - go

Starting from Go 1.16, ioutil.ReadAll, ioutil.ReadFile and ioutil.ReadDir are deprecated, as the package io/ioutil is deprecated.
What other stdlib packages provide the same functionality?

ioutil.ReadAll -> io.ReadAll
ioutil.ReadFile -> os.ReadFile
ioutil.ReadDir -> os.ReadDir
// others
ioutil.NopCloser -> io.NopCloser
ioutil.ReadDir -> os.ReadDir
ioutil.TempDir -> os.MkdirTemp
ioutil.TempFile -> os.CreateTemp
ioutil.WriteFile -> os.WriteFile

Related

Error undefined: imagick.Initialize while using imagick

I am using the gopkg.in/gographics/imagick.v2/imagick package but it shows the error while running the server : undefined: imagick.Initialize
import "gopkg.in/gographics/imagick.v2/imagick"
func ConvertPdfToJpg() {
imagick.Initialize()
defer imagick.Terminate()
mw := imagick.NewMagickWand()
defer mw.Destroy()
mw.ReadImage("test.pdf")
mw.SetIteratorIndex(0)
mw.SetImageFormat("jpg")
mw.WriteImage("test.jpg")
}
Please check out readme from the project.
Go Imagick is a Go bind to ImageMagick's MagickWand C API.
You need to install ImagMagick first, and then you can use go bindings.

Go WASM export functions

I want to create a .wasm file which still has the function names exported when compiled.
package main
import (
"fmt"
)
func main() {
fmt.Println("Main")
}
func MyFunc() {
fmt.Println("MyFunc")
}
I'm building with
GOOS=js GOARCH=wasm go build -o main.wasm
Which produces the wasm file (and awesome that Go targets wasm natively).
But using wabt and doing an object dump exposes these functions.
Export[4]:
- func[958] <wasm_export_run> -> "run"
- func[959] <wasm_export_resume> -> "resume"
- func[961] <wasm_export_getsp> -> "getsp"
- memory[0] -> "mem"
I'm expecting to see something like
func[137] <MyFunc> -> "MyFunc"
Does anyone know how to export functions in Go WASM?
In rust including #[no_mangle] and pub extern "C" keeps the function available in the output with wasm-pack. I'm looking for something similar with Go.
If you plan to write a lot of WASM in Go, you might want to consider compiling with TinyGo, which is a Go compiler for embedded and WASM.
TinyGo supports a //export <name> or alias //go:export <name> comment directive that does what you're looking for.
I'm copy-pasting the very first example from TinyGo WASM docs:
package main
// This calls a JS function from Go.
func main() {
println("adding two numbers:", add(2, 3)) // expecting 5
}
// ...omitted
// This function is exported to JavaScript, so can be called using
// exports.multiply() in JavaScript.
//export multiply
func multiply(x, y int) int {
return x * y;
}
And you build it with: tinygo build -o wasm.wasm -target wasm ./main.go.
The standard Go compiler has an ongoing open discussion about replicating TinyGo feature. The tl;dr seems to be that you can achieve this by setting funcs to the JS global namespace, with the js.Global().Set(...)

Go import from package's vendor

How can I specify to import/use a package from the vendor instead from the GOPATH/GOROOT?
$GOPATH/src/
$GOPATH/src/github.com/
$GOPATH/src/github.com/myproject/mypkg
$GOPATH/src/github.com/myproject/mypkg/mypkgfile1.go
package mypkg
import "github.com/someproject/somepkg" // importing from vendor
type MyStruct struct {
Config somepkg.SomeStruct1
}
func New(config somepkg.SomeStruct1) MyStruct {...}
func (m *MyStruct) DoSomething() {
a := somepkg.SomeStruct1{}
b := somepkg.SomeStruct2{}
// do something with 'a' and 'b'
out := somepkg.SomeFunc(a)
}
func (m *MyStruct) MyFunc(input SomeStruct1) (output SomeStruct2, err error) {...}
$GOPATH/src/github.com/myproject/mypkg/mypkgfile2.go
$GOPATH/src/github.com/myproject/mypkg/vendor/github.com/someproject/somepkg/
$GOPATH/src/github.com/myproject/mypkg/vendor/github.com/someproject/somepkg/somepkgfile1.go
package somepkg
type SomeStruct1 struct {...}
type SomeStruct2 struct {...}
func SomeFunc(input SomeStruct1) (output SomeStruct2) {...}
$GOPATH/src/github.com/myproject/mypkg/go.mod
module gitHub.com/myproject/mypkg
go 1.1.4
require github.com/someproject/somepkg v1.0.0
$GOPATH/src/github.com/someproject/somepkg/somepkgfile1.go
package somepkg
type SomeStruct1 struct {...}
type SomeStruct2 struct {...}
func SomeFunc() {...}
$GOPATH/src/github.com/someproject/somepkg/go.mod
module gitHub.com/someproject/somepkg
go 1.1.4
require github.com/someproject/somepkg v1.0.0
$GOPATH/src/github.com/anotherproject/anotherpkpg/somepkgfile1.go
package main
import (
"github.com/someproject/somepkg"
"github.com/myproject/mypkg"
)
func main() {
// do something with somepkg
somepkg.SomeFunc()
s := somepkg.SomeStruct1{...}
myData := mypkg.New(s)
m := mypkg.MyFunc()
x := somepkg.SomeStruct1{...}
y := mypkg.MyFunc(x)
}
$GOPATH/src/github.com/someproject/somepkg/go.mod
module gitHub.com/someproject/somepkg
go 1.1.4
require (
github.com/myproject/mypkg v1.0.0
github.com/someproject/somepkg v1.0.0
)
When I'm building/running anotherpkpg/main.go I keep getting a type mismatch error like:
cannot use &s (type *"someproject/somepkg".SomeStruct1) as type *"myproject/mypkg/vendor/github.com/someproject/somepkg".SomeStruct1 in argument to mypkg.New
Its not possible at all to be able do this? I get it that type mismatch can occur if the somepkg are of different version/releases. But There is no way to reference the vendored somepkg? I would think it would get even more complex when i
vendor directories work differently in GOPATH mode than in module mode.
Since github.com/myproject/mypkg/go.mod exists, you are presumably building github.com/myproject/mypkg and its dependencies in module mode. In module mode, only the vendor contents for the main module are used, and vendor directories for other packages are always ignored, so each package has exactly one location and one definition. (With -mod=vendor each package is loaded from your vendor directory; with -mod=readonly or -mod=mod each package is loaded from the module cache.)
Since github.com/anotherproject/anotherpkg/go.mod does not exist, Go 1.15 and earlier will by default build it in GOPATH mode. In GOPATH mode, the import statements within each directory refer to the packages in the vendor subtrees of all parent directories, and the vendored packages are treated as distinct packages even if they share the same import path.
The right long-term fix for your situation is probably to start building github.com/anotherproject/anotherpkg in module mode, and to use a replace directive if needed to point it at your working copy of github.com/myproject/mypkg.
You can set that up using a sequence of commands like:
# Enable module mode for anotherpkg.
cd $GOPATH/src/github.com/anotherproject/anotherpkg
go mod init github.com/anotherproject/anotherpkg
# Use the local copy of github.com/myproject/mypkg instead of the latest GitHub snapshot.
go mod edit -replace github.com/myproject/mypkg=$GOPATH/src/github.com/myproject/mypkg
go get -d github.com/myproject/mypkg
# Resolve any additional missing dependencies to their latest versions.
go mod tidy

Is there any way to create an alias of a specific FnMut?

I want to work with FnMut(&[f32]) -> f32,
to not copy/paste full signature, I want to introduce some kind of alias, but
type Boo = FnMut(&[f32]) -> f32;
fn f<F: Boo>(mut f: F) {}
Causes a compiler error:
error[E0404]: expected trait, found type alias `Boo`
--> src/main.rs:3:13
|
3 | fn f<F: Boo>(mut f: F) {}
| ^^^ type aliases cannot be used for traits
I then tried:
trait Boo: FnMut(&[f32]) -> f32 {}
fn f<F: Boo>(mut f: F) {}
it compiled, but if I try to use Boo in place of trait in another place:
trait Boo: FnMut(&[f32]) -> f32 {}
struct X(Vec<Box<Boo>>);
I get:
error[E0191]: the value of the associated type `Output` (from the trait `std::ops::FnOnce`) must be specified
--> src/main.rs:3:18
|
3 | struct X(Vec<Box<Boo>>);
| ^^^ missing associated type `Output` value
Is there any way to create an alias of a specific FnMut which I can use
instead of FnMut(&[f32]) -> f32?
Trait aliases are not currently part of the language. However, there is an accepted RFC for exactly that. It's hard to predict exactly when it will be implemented, but accepting the RFC represents a commitment to implement it at some point in the future.
The reason for your error is that your Boo trait is a subtype of FnMut and any implementation must also provide the required associated type Output. But the compiler still doesn't know which implementation will be provided, so you need to tell it what the type of Output will be:
struct X(Vec<Box<Boo<Output = f32>>>);
This is a little clunky, and I feel like it's an area for improvement. Intuitively, it seems that Output could be inferred from -> f32, but I could be wrong here.
Even with that error fixed, Boo is strictly a subtype of FnMut(&[f32]) so you can't just provide any closure where Boo is expected. That closure must also implement your trait. You can do this as a blanket implementation for all FnMut(&[f32]) -> f32, like this:
impl <F> Boo for F where F: FnMut(&[f32]) -> f32 {}
Now any Boo is an FnMut(&[f32]) -> f32 (by subtyping), and any FnMut(&[f32]) -> f32 is a Boo (by the blanket implementation).

Using the gofmt refactoring tool to rename a global variable

I'm experimenting the gofmt tool capabilities for refactoring go code based on this blog post, I have this trivial example:
package main
import (
"fmt"
)
var v = 12
func main() {
fmt.Println(v)
}
I'm trying to rename the v variable to mapplying this recipe:
gofmt -r 'v -> m' -w main.go
The code after the refactoring looks (broken) like:
package m
import (
"fmt"
)
var m = m
func m() {
m
}
What am I missing here?
There is a problem with what you're trying, the gofmt manual states:
The rewrite rule specified with the -r flag must be a string of the form:
pattern -> replacement
Both pattern and replacement must be valid Go expressions. In the pattern, single-character lowercase >identifiers serve as wildcards matching arbitrary sub-expressions; those expressions will be substituted for the same identifiers in the replacement.
(highlighting added)
If you had var vee = 12 and used -r vee -> foo everything would be fine. With v -> m however,
v -> m matches every Go expression, identifies it as v and replaces it by m.

Resources