I am new to Go and was working through a problem in The Go Programming Language. The code should create GIF animations out of random Lissajous figures with the images being produced in the different colors from palate
:
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
// Run with "web" command-line argument for web server.
// See page 13.
//!+main
// Lissajous generates GIF animations of random Lissajous figures.
package main
import (
"image"
"image/color"
"image/gif"
"io"
"math"
"math/rand"
"os"
)
//!-main
// Packages not needed by version in book.
import (
"log"
"net/http"
"time"
)
//!+main
// #00ff55
var palette = []color.Color{color.RGBA{0x00, 0xff, 0x55, 0xFF}, color.Black, color.RGBA{0x00, 0x00, 0xff, 0xFF}, color.RGBA{0xff, 0x00, 0xff, 0xFF}}
const (
whiteIndex = 0 // first color in palette
)
func main() {
//!-main
// The sequence of images is deterministic unless we seed
// the pseudo-random number generator using the current time.
// Thanks to Randall McPherson for pointing out the omission.
rand.Seed(time.Now().UTC().UnixNano())
if len(os.Args) > 1 && os.Args[1] == "web" {
//!+http
handler := func(w http.ResponseWriter, r *http.Request) {
lissajous(w)
}
http.HandleFunc("/", handler)
//!-http
log.Fatal(http.ListenAndServe("localhost:8000", nil))
return
}
//!+main
lissajous(os.Stdout)
}
func lissajous(out io.Writer) {
const (
cycles = 5 // number of complete x oscillator revolutions
res = 0.001 // angular resolution
size = 100 // image canvas covers [-size..+size]
nframes = 64 // number of animation frames
delay = 8 // delay between frames in 10ms units
)
freq := rand.Float64() * 3.0 // relative frequency of y oscillator
anim := gif.GIF{LoopCount: nframes}
phase := 0.0 // phase difference
colorIndex := 2
for i := 0; i < nframes; i++ {
rect := image.Rect(0, 0, 2*size+1, 2*size+1)
img := image.NewPaletted(rect, palette)
for t := 0.0; t < cycles*2*math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), colorIndex)
colorIndex++
}
phase += 0.1
anim.Delay = append(anim.Delay, delay)
anim.Image = append(anim.Image, img)
}
gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors
}
//!-main
Here is the error I am getting
lissajous/main.go:76: cannot use colorIndex (type int) as type uint8 in argument to img.SetColorIndex
Is there a difference between int and uint8 types or something?
The type of colorIndex
is int
. The argument type is uint8
. An int
cannot be assigned to a uint8
. Here are some options for fixing the program:
Declare colorIndex
as an untyped constant.
const colorIndex = 2
Declare colorIndex
as uint8 type:
colorIndex := uint8(3)
Convert the value at the call:
img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), uint8(colorIndex))
You can replace all uses of uint8
in this answer with byte
because byte
is an alias for uint8
.
In variable declarations, a default type is used, and in your case, colorIndex := 2
, i.e. colorIndex becomes int, not uint8.
From the docs ( https://golang.org/ref/spec#Short_variable_declarations ): "If a type is present, each variable is given that type. Otherwise, each variable is given the type of the corresponding initialization value in the assignment. If that value is an untyped constant, it is first converted to its default type;..."
"var i = 42 // i is int"
and then
"An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required, for instance, in a short variable declaration such as i := 0 where there is no explicit type. The default type of an untyped constant is bool, rune, int, float64, complex128 or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant."
So to get uint8, you should either explicitly declare colorIndex as uint8 var colorIndex uint8 = 2
or cast uint8 in img.SetColorIndex as :
img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), uint8(colorIndex))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With