Add a method called 'isLetter', which takes a parameter 'ch' of type char and
returns a value of type boolean. If 'ch' is a letter from a..z or A..Z then it
returns true otherwise it returns false
I tried adding the method but i just kept getting errors
Related
When I try to assign an implicitly typed constant to a variable, the assigned variable doesn't detect the custom type and instead gets assigned as the underlying primitive type. i.e;
For:
type Custom string
const (
First Custom = "10"
Second = "20"
)
If I have a function:
func SomeFunc( x Custom) {
fmt.Printf("Inside func %v %v", x, reflect.TypeOf(x))
}
Then when I:
out := Second
SomeFunc(out)
it errors with:
cannot use out (type string) as type Custom in argument to SomeFunc
However SomeFunc(Second) works fine.
Also
fmt.Printf("%v %v\n",reflect.TypeOf(second),reflect.TypeOf(out)) //prints string string
Here is the reproducer: https://play.golang.org/p/Iv-C1ee992
Can someone help me understand what is happening here?
Second is an untyped const and has this property (https://blog.golang.org/constants):
An untyped constant is just a value, one not yet given a defined type
that would force it to obey the strict rules that prevent combining
differently typed values.
...
Assigning them to a variable of any type compatible with strings works
without error.
On the contrary out is a variable of type string. Again from the blog post:
and by now you might be asking, "if the constant is untyped, how does
str get a type in this variable declaration?" The answer is that an
untyped constant has a default type, an implicit type that it
transfers to a value if a type is needed where none is provided. For
untyped string constants, that default type is obviously string
This code works fine:
feedService := postgres.FeedService{}
feeds, err := feedService.GetAllRssFeeds()
But this code gives me error:
feeds, err = postgres.FeedService{}.GetAllRssFeeds()
controllers\feed_controller.go:35: cannot call pointer method on
postgres.FeedService literal controllers\feed_controller.go:35: cannot
take the address of postgres.FeedService literal
Why this two pieces of code is not equal ?
Here is a struct declaration:
type FeedService struct {
}
func (s *FeedService) GetAllRssFeeds() ([]*quzx.RssFeed, error) {
Your FeedService.GetAllRssFeeds() method has pointer receiver, so a pointer to FeedService is needed to call this method.
In your first example you use a short variable declaration to store a FeedService struct value in a local variable. Local variables are addressable, so when you write feedService.GetAllRssFeeds() after that, the compiler will automatically take the address of feedService and use that as the receiver value. It is a shorthand for:
feeds, err := (&feedService).GetAllRssFeeds()
It is in Spec: Calls:
If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().
In your second example you don't create a local variable, you just use a struct composite literal, but by itself it is not (automatically) addressable, so the compiler cannot obtain a pointer to FeedService value to be used as the receiver, and hence cannot call the method.
Note that it is allowed to take the address of a composite literal explicitly, so the following also works:
feeds, err := (&postgres.FeedService{}).GetAllRssFeeds()
This is in Spec: Composite literals:
Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.
See related questions:
What is the method set of `sync.WaitGroup`?
Calling a method with a pointer receiver by an object instead of a pointer to it?
I am curious about IsValid function, because during my use of this function, it never returned false. So when does it return a negative result?
As the doc reflect.IsValid() says:
It returns false if v is the zero Value. [...]
Most functions and methods never return an invalid value. If one does, its documentation states the conditions explicitly.
Value.IsValid() is supposed to report whether the reflect.Value itself is valid, not the value it wraps (if any).
All the examples below print false. You can try them on the Go Playground.
The simplest example is calling IsValid() on the zero value of reflect.Value (which is a struct):
fmt.Println(reflect.Value{}.IsValid())
The 2nd simplest example is when passing nil to reflect.ValueOf():
fmt.Println(reflect.ValueOf(nil).IsValid())
Another example: start with a pointer being nil, in this case there is no "pointed" value, a nil pointer points to nowhere. Attempting to get the reflect.Value of the pointed value using Value.Elem() results in a zero reflect.Value whose IsValid() method will return false:
var i *int
v := reflect.ValueOf(i)
v2 := v.Elem()
fmt.Println(v2.IsValid())
Or in one line:
fmt.Println(reflect.ValueOf((*int)(nil)).Elem().IsValid())
Same thing if you call Value.Indirect() on the above reflect.Value():
fmt.Println(reflect.Indirect(v).IsValid())
Or attempting to get a non-existing struct field by name using Value.FieldByName():
s := struct{}{}
fmt.Println(reflect.ValueOf(s).FieldByName("").IsValid())
Or attempting to get a non-existing method by name using Value.MethodByName():
fmt.Println(reflect.ValueOf(s).MethodByName("").IsValid())
Or attempting to get a value from a map by a non-existing key using Value.MapIndex():
m := map[int]int{}
fmt.Println(reflect.ValueOf(m).MapIndex(reflect.ValueOf(3)).IsValid())
The list goes on...
Why don't I have to define PrintValue() as a pointer receiver (*One) to be able to print "hello"?
package main
import "fmt"
type One struct{
a string
}
func (o *One)AssignValue(){
o.a = "hello"
}
func (o One)PrintValue(){
fmt.Println(o.a)
}
func main() {
one := One{}
one.AssignValue()
one.PrintValue()
}
Because one is already of type One. The instantiation syntax
t := One{}
creates a value of type One while the form
p := &One{}
creates a pointer to a value of type One.
This means that nothing is to be done when calling t.PrintValue as the receiver type (One) is already the same as the type of t (One as well).
When calling p.PrintValue the compiler automatically converts an addressable variable to its pointer form because the receiver type (One) is not equal to the type of p (*One). So the expression
p.PrintValue()
is converted to
(*p).PrintValue()
There is also a conversion necessary when calling t.AssignValue as this method has a pointer receiver but we're supplying a value. This is also done automatically by the compiler where possible.
From the spec on calls:
A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m()
This means the expression
t.AssignValue()
is converted to
(&t).AssignValue()
Note that this is not always possible. For example when returning a value from a function:
func NewOne(s string) One { return One{s} }
NewOne("foo").AssignValue() // Not possible
x := NewOne("foo")
x.AssignValue() // Possible, automatically converted
I'm using enum method name() to print the string value of an enum variable.
Should I do a null check first?
The name() method cannot return null. It will return an empty string if the value does not correspond to an enumerated value. It may be advisable to do an empty string check.
Quoting from IEEE std 1800-2012 ยง 6.19.5.6 Name()
The name() method returns the string representation of the given enumeration value. If the given value is not a member of the enumeration, the name() method returns the empty string.
No, you don't need to worry about a null enum. However, an enum could be un-initialized if it does not have a state corresponding to 0
For example:
typedef enum {STATE0, STATE1} plain_enum;
typedef enum {VAL0=1, VAL1} special_enum;
module test;
initial begin
plain_enum plain;
special_enum special;
$display("plain: %s", plain.name());
$display("special: %s", special.name());
end
endmodule
Returns:
# plain: STATE0
# special:
Because special_enum does not have a state corresponding to 0
Edit/re-run the code here: http://www.edaplayground.com/s/4/647