Conversion of constants

In case you missed it… It has come to my attention that Monday’s livestream went to the wrong stream on YouTube! This means if you followed the link I shared with you on Monday, you likely sat there waiting for 2 hours, only to be disappointed by a lack of live programming. 😞 Alas, the livestream did happen, just at a different link by accident. So here’s that link, so you can watch the replay, if you so desire.


Ambiguous conversion expressions

There aren’t many places where Go syntax is ambiguous, but here’s one: Conversions … If the type starts with the operator * or <-, or if the type starts with the keyword func and has no result list, it must be parenthesized when necessary to avoid ambiguity: *Point(p) // same as *(Point(p)) (*Point)(p) // p is converted to *Point <-chan int(c) // same as <-(chan int(c)) (<-chan int)(c) // c is converted to <-chan int func()(x) // function signature func() x (func())(x) // x is converted to func() (func() int)(x) // x is converted to func() int func() int(x) // x is converted to func() int (unambiguous) Of these three ambiguous cases, * is the one you’re most likely to run into, so let’s look at an example.


Conversions

On todays’s livestream, we’ll be Pair Programming on a real project. I hope to see you there! Conversions A conversion changes the type of an expression to the type specified by the conversion. A conversion may appear literally in the source, or it may be implied by the context in which an expression appears. An explicit conversion is an expression of the form T(x) where T is a type and x is an expression that can be converted to type T.


Receive operator

Reminder! On Monday’s livestream, we’ll be Pair Programming on a real project. Don’t miss it! Channels are deceptively simple. They seem a bit magical. They feel like they do something. They feel like they send data around your system. But they really don’t. They’re just data types. They’re probably best thought of like Go’s array or slice type, with the limitation that you can only ever read the first value, and you can only ever set the last value.

Subscribe to Boldly Go: Daily

Every day I'll send you advice to improve your understanding of Go. Don't miss out! I will respect your inbox, and honor my privacy policy.

Unsure? Browse the archive.

Other

1 min read


Live pair programming on a real project

Mark your calendar! If you’ve ever been curious about pair programming, and want to see it in action on a real project, not just a coding exercise, you’ll want to join Monday’s livestream. I’ll be doing some live Pair Programming with Denis Čahuk and Adrian Stanek. Denis and Adrian invited me to their livestream a couple of weeks ago, to talk about Test-Driven Development. You can watch that replay on YouTube.


Address operators

Let’s talk about addresses. Address operators For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. This leads to one of my great annoyances about the Go language.


Logical operators

Logical operators Logical operators apply to boolean values and yield a result of the same type as the operands. The left operand is evaluated, and then the right if the condition requires it. && conditional AND p && q is "if p then q else false" || conditional OR p || q is "if p then true else q" ! NOT !p is "not p" I think this is pretty intuitive.


Introducing Go 1.22!

Join me in less than an hour, when I’ll be live streaming again! I’ll be continuing to add SQLite support to Kivik, using Test-Driven Development. Go 1.22 was released on February 7. So I’m a bit behind on talking about the changes introduced to the spec. But better late than never! If you’re interested in my thoughts on some of the other changes, including those to the standard library, check out last week’s episode of the Cup o’ Go podcast.


Comparison operators, conclusion

Comparison operators … Slice, map, and function types are not comparable. However, as a special case, a slice, map, or function value may be compared to the predeclared identifier nil. Comparison of pointer, channel, and interface values to nil is also allowed and follows from the general rules above. Let’s demonstrate: var a func() var b []int var c map[string]string fmt.Println(a == nil, b == nil, c == nil) // true, true, true But this only applies to a direct comparison with nil.


Comparison operators, part IV

Comparison operators … Struct types are comparable if all their field types are comparable. Two struct values are equal if their corresponding non-blank field values are equal. The fields are compared in source order, and comparison stops as soon as two field values differ (or all fields have been compared). I think this is clear. But it leads to some interesting things in the wild, when you want structs to not be comparable.


Comparison operators, part III

Today we continue through the list of data types and how comparison and ordering works on each. Comparison operators … Channel types are comparable. Two channel values are equal if they were created by the same call to make or if both have value nil. Notice that channel comparison is effectively a comparison of identity. Not type or content. Two channels may have the same type and contents, but be unequal: