In Apple's "A swift Tour" they have this code snippet:
enum OptionalValue<T> {
case None
case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)
How would you get the 100? You can't do possibleInteger == 100 to test if possibleInteger has the value 100 inside. I know you can put functions inside enumerations, but you can't have variables. Maybe I'm understanding enumerations wrong…
If I command click Optional when declaring an optional (var x:Optional<Int>), I can find
enum Optional<T> : Reflectable, NilLiteralConvertible {
case None
case Some(T)
init()
init(_ some: T)
/// Haskell's fmap, which was mis-named
func map<U>(f: (T) -> U) -> U?
func getMirror() -> MirrorType
static func convertFromNilLiteral() -> T?
}
But I do not understand what any of that means. Help?
You can use a switch statement to get the value, as described here. Relevant bit:
... the associated values can be extracted as part of the switch
statement. You extract each associated value as a constant (with the
let prefix) or a variable (with the var prefix) for use within the
switch case’s body:
For your case, you'd want something like:
switch possibleInteger {
case .Some(let value):
println(value)
case .None:
println("<None>")
}
Related
I'm coming from an Scala background, and in Scala, you could define functions both as a single value, or an actual function, for instance:
val inc1: Int => Int = _ + 1 // single FUNCTION value
def inc2(x: Int): Int = x + 1 // normal function definition
// in this case "inc1 eq inc1" is true, since this is a single instance
// but "inc2 eq inc2" is false
And these 2 have some differences (i.e., size allocation, first one is a single instance, while the other one returns an instance each time it is invoked, ...), so based on the use case, we could kind of reason which one to use. Now I'm new to golang, and wanted to know if the below 2 function definitions (correct me if I'm wrong with the phrase) differ in Golang, and if so, what are differences?
var inc1 = func(x int) int { return x + 1 }
func inc2(x int) int { return x + 1 }
Thanks in advance!
Scala borrows a lot from functional programming. Go does not.
(If you've used multiple other programming languages, you should definitely read the Go specification. It's not very long as Go is not a very large language, although the new generics definitely complicate things a bit.)
In Go, the func keyword introduces a function definition or function type, with the details being context-dependent. The var keyword introduces a variable declaration.1 So:
func inc2(x int) int { return x + 1 }
defines a function, inc2, whose code is as shown. But:
var inc1 = // ...
declares and then initializes a variable, inc1. The type and initial value of the variable are determined by the commented-out section, so:
var inc1 = func(x int) int { return x + 1 }
defines a function (with no name) whose code is as shown. That function is then assigned to the variable as its initial value, so that the implied type of the variable is func (int) int or function taking one argument of type int and returning one value of type int.
Having created a variable, you can now either call the function currently stored in that variable:
func callit(arg int) {
result := inc1(arg)
// ... do something with the result ...
}
Or you can assign a new value into the variable, e.g.:
func overwrite() {
inc1 = func(a int) int { return a * 2 } // name `inc1` is now misleading
}
Because inc2 is a function, you can't re-assign a new value to it: it's just a function, not a variable.
1Note that a variable declaration with an initialization can use the "short declaration" form:
func f() {
v := 3
// ...
}
where we leave out the type and just say "use the type of the expression to figure out the type of the declaration". This declares and initializes the variable. Short declarations can only appear in block scope, so these must be inside some function. Other than omitting the var keyword they do nothing that you couldn't do by including the var keyword, or sometimes multiple var keywords:
result, err := doit()
might require:
var result someType
var err error
result, err = doit()
when written without using the short-declaration form.
What's the difference between these two functions?
func f[_ string, p string](s ...p) {
fmt.Println(s)
}
func f[p string](s ...p) {
fmt.Println(s)
}
Why even put a blank identifier in a type parameter in the first place?
Using underscore _ in place of a type parameter name simply signals that the type parameter is not used within the function scope.
In your example code, it doesn't really make a difference; both versions of f can be called as f("blah") without supplying explicit type parameters. But this is possible only because the constraint string restricts to an exact type. It can only ever be string, so type inference still works.
If you change it to an approximate type instead it has to be instantiated explicitly:
// can't infer first type param from anywhere
func f[_ ~string, P ~string](s ...P) {
fmt.Println(s)
}
func main() {
// must supply first type param, may omit second one
f[string]("blah")
}
In real world scenarios where constraints are not exact types, the underscore would likely force callers to specify the type parameter: this effectively would break backward compatibility, because client code must indeed be updated to work.
Just to be clear, this applies to type parameters that are independent of each other. If the underscored type parameter can be inferred from another one, it can still compile without explicit instantiation:
// called as foo("blah")
func foo[T ~string, P *T](t T) {
var p P = &t
fmt.Println(t, p)
}
// still called as foo("blah")
func foo[T ~string, _ *T](t T) {
fmt.Println(t)
}
However it's worth noting that if a function has two independent type parameters that are inferrable from arguments:
func f[T any, U any](t T, u U) {
fmt.Println(t, u)
}
...making U not inferrable implies also removing the u U argument too, so you already have a backward-incompatible change.
// one less argument, requires major version upgrade anyway
func foo[T any, _ any](t T) {
fmt.Println(t, u)
}
With methods instead, it's a different story. Since methods can't specify type parameters that weren't declared on the receiver type, using underscore is a much more frequent occurrence. It may just happen that some methods do not need all type parameters. Then the underscore aptly reflects that:
type Foo[T,U any] struct {
ID T
Val U
}
// we do not need to reference U here
func (f *Foo[T,_]) SetID(t T) {
f.ID = t
}
// we do not need to reference T here
func (f *Foo[_,U]) SetVal(v U) {
f.Val = v
}
I'm trying to create a function that will produce an if condition from a predefined array.
for example:
package errors
type errorCase struct {
// This is the field I need to get in another struct
Field string
// The comparison operator
TestOperator string
// The value that the expected one should not with equal...
WrongValue interface{}
}
var ErrorCases = []*errorCase{ {
"MinValue",
"<",
0,
}, {
"MaxValue",
"==",
0,
}}
Actually I made a new function with a for loop that iterate through all of these "error cases"
func isDirty(questionInterface models.QuestionInterface) bool {
for _, errorCase := range errors.ErrorCases {
s := reflect.ValueOf(&questionInterface).Elem()
value := s.Elem().FieldByName(errorCase.Field)
// At this point I need to create my if condition
// to compare the value of the value var and the wrong one
// With the given comparison operator
}
// Should return the comparison test value
return true
}
Is that possible to create an if condition like that?
With the reflect package?
I think this is possible but I don't find where I should start.
This is possible. I built a generic comparison library like this once before.
A comparison, in simple terms, contains 3 parts:
A value of some sort, on the left of the comparison.
An operator (=, <, >, ...).
A value of some sort, on the right of the comparison.
Those 3 parts, contain only two different types - value and operator. I attempted to abstract those two types into their base forms.
value could be anything, so we use the empty interface - interface{}.
operator is part of a finite set, each with their own rules.
type Operator int
const (
Equals Operator = 1
)
Evaluating a comparison with an = sign has only one rule to be valid - both values should be of the same type. You can't compare 1 and hello. After that, you just have to make sure the values are the same.
We can implement a new meta-type that wraps the requirement for evaluating an operator.
// Function signature for a "rule" of an operator.
type validFn func(left, right interface{}) bool
// Function signature for evaluating an operator comparison.
type evalFn func(left, right interface{}) bool
type operatorMeta struct {
valid []validFn
eval evalFn
}
Now that we've defined our types, we need to implement the rules and comparison functions for Equals.
func sameTypes(left, right interface{}) bool {
return reflect.TypeOf(left).Kind() == reflect.TypeOf(right).Kind()
}
func equals(left, right interface{}) bool {
return reflect.DeepEqual(left, right)
}
Awesome! So we can now validate that our two values are of the same type, and we can compare them against each other if they are. The last piece of the puzzle, is mapping the operator to its appropriate rules and evaluation and having a function to execute all of this logic.
var args = map[Operator]operatorMeta{
Equals: {
valid: []validFn{sameTypes},
eval: equals,
},
}
func compare(o Operator, left, right interface{}) (bool, error) {
opArgs, ok := args[o]
if !ok {
// You haven't implemented logic for this operator.
}
for _, validFn := range opArgs.valid {
if !validFn(left, right) {
// One of the rules were not satisfied.
}
}
return opArgs.eval(left, right), nil
}
Let's summarize what we have so far:
Abstracted a basic comparison into a value and operator.
Created a way to validate whether a pair of values are valid for an operator.
Created a way to evaluate an operator, given two values.
(Go Playground)
I hope that I gave some insight into how you can approach this. It's a simple idea, but can take some boilerplate to get working properly.
Good luck!
I have the following code where every variant of the enum Message has a Term value associated with it:
type Term = usize;
pub enum Message {
AppendRequest(Term),
AppendResponse(Term),
VoteRequest(Term),
VoteResponse(Term),
}
impl Message {
pub fn term(&self) -> Term {
match *self {
Message::AppendRequest(term) => term,
Message::AppendResponse(term) => term,
Message::VoteRequest(term) => term,
Message::VoteResponse(term) =>term,
}
}
}
I want to, given a Message be able to get its term without having to deconstruct the actual Message value I have. The best I could come up with was creating a public function that unpacked the value for me, but this feels clunky. If I ever add a new enum value, I'm going to have to remember to update match statement in the term function.
Is there a more succinct/ergonomic way to express the code above? Is there some way to say "hey, every value for this enum will have also have a Term value associated with it.
Is there some way to say "hey, every value for this enum will have also have a Term value associated with it.
No. This is usually handled by splitting the enum into two parts, with a struct containing all the common parts:
pub struct Message {
term: Term,
kind: MessageKind,
}
pub enum MessageKind {
AppendRequest,
AppendResponse,
VoteRequest,
VoteResponse,
}
One option is to implement the Deref (and/or DerefMut) trait to convert to the common part.
You still have to update that implementation each time you add to the Enum, but there is less boilerplate at the point of use.
E.g., an example below, note that main accesses the field number on the Enum.
use std::ops::Deref;
use std::string::String;
enum JudgedNumber {
GoodNumber(Number),
BadNumber(Number, String),
}
struct Number { number: i32 }
fn main() {
let nice = JudgedNumber::GoodNumber(Number{number: 42});
let naughty = JudgedNumber::BadNumber(
Number{number: 666}, "Damn you to hell".to_string());
println!("j1 = {}", j1.number);
println!("j2 = {}", j2.number);
}
impl Deref for JudgedNumber {
type Target = Number;
fn deref(&self) -> &Number {
match self {
JudgedNumber::GoodNumber(n) => n,
JudgedNumber::BadNumber(n, _) => n,
}
}
}
I learnt this from https://github.com/rust-embedded/svd/blob/master/src/svd/cluster.rs
I have problem with resolve whether object which was pass as interface to function hasn't initializated fields, like object which was defined as just someObject{} is a empty, because all fields, has value 0, or nil
Problem becomes more complicated if I pass diffrent objects, because each object have diffrent type field value so on this moment I don't find universal way to this.
Example
func main(){
oo := objectOne{}
ot := objectTwo{}
oth := objectThree{"blah" , "balbal" , "blaal"}
resolveIsNotIntialized(oo)
resolveIsNotIntialized(ot)
resolveIsNotIntialized(oth)
}
func resolveIsNotIntialized(v interface{}) bool{
// and below, how resolve that oo and ot is empty
if (v.SomeMethodWhichCanResolveThatAllFiledIsNotIntialized){
return true
}
return false
}
I want to avoid usage switch statement like below, and additional function for each object, ofcorse if is possible.
func unsmartMethod(v interface{}) bool{
switch v.(type){
case objectOne:
if v == (objectOne{}) {
return true
}
// and next object, and next....
}
return false
}
As Franck notes, this is likely a bad idea. Every value is always initialized in Go. Your actual question is whether the type equals its Zero value. Generally the Zero value should be designed such that it is valid. The better approach would generally be to create an interface along the lines of:
type ZeroChecker interface {
IsZero() bool
}
And then attach that to whatever types you want to check. (Or possibly better: create an IsValid() test instead rather than doing your logic backwards.)
That said, it is possible to check this with reflection, by comparing it to its Zero.
func resolveIsNotIntialized(v interface{}) bool {
t := reflect.TypeOf(v)
z := reflect.Zero(t).Interface()
return reflect.DeepEqual(v, z)
}
(You might be able to get away with return v == z here; I haven't thought through all the possible cases.)
I don’t think there is a good reason (in idiomatic Go) to do what you are trying to do. You need to design your structs so that default values (nil, empty string, 0, false, etc.) are valid and represent the initial state of your object. Look at the source of the standard library, there are lots of examples of that.
What you are suggesting is easily doable via Reflection but it will be slow and clunky.
You could narrow the type which your function takes as an argement a little, not take an interface{} but accept one that allows you to check for non-zero values, say type intercae{nonZero() bool} as in the example code below. This will not tell you explicitly that it hasn't been set to the zero value, but that it is not zero.
type nonZeroed interface {
nonZero() bool
}
type zero struct {
hasVals bool
}
func (z zero) nonZero() bool {
return z.hasVals
}
type nonZero struct {
val int
}
func (nz nonZero) nonZero() bool {
return nz.val != 0
}
type alsoZero float64
func (az alsoZero) nonZero() bool {
return az != 0.0
}
func main() {
z := zero{}
nz := nonZero{
val: 1,
}
var az alsoZero
fmt.Println("z has values:", initialized(z))
fmt.Println("nz has values:", initialized(nz))
fmt.Println("az has values:", initialized(az))
}
func initialized(a nonZeroed) bool {
return a.nonZero()
}
Obviously as the type get more complex additional verification would need to be made that it was "nonZero". This type of pattern could be used to check any sort condition.