Why a pointer needs to be returned when the return type is actually error? - pointers

I am reading the article Error handling and Go, and don't quite understand why a pointer (&errorString{text}) has to be returned when the return type is actually error?
My understanding is error is an interface, and errorString implements the interface, therefore, return errorString is also okay (but it is not the case).
// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}
errorString implementation
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}

Because error interface for errorString is implemented for a pointer (func (e *errorString) Error()), if it was implemented like below you would return the value directly:
func (e errorString) Error() string {
return e.s
}

Related

Interfaces and address operators

I have a problem to understand why the address operator can be used when the return type is an interface
func NewReader() IReader {
return &Reader{}
}
but (of course) not when a return type is a struct
func NewReader() Reader {
return &Reader{} // cannot use &Reader literal (type *Reader) as type Reader in return argument
}
The function signature later is func MyFuncReader(r IReader) but the reflect.TypeOf(r) is *main.Reader.
So the type IReader is hiding the fact that it is pointer?
The function signature func MyFuncReader(r IReader) doesn't tell me, that a pointer or a value was passed the func?
Samples
Full Sample with interface https://play.golang.org/p/1Db1Jybp0rP
Full Sample without interface https://play.golang.org/p/nPtu09yhe0C
If the return type of a function is an interface type, you may return any values that implement that interface. Spec: Return statements:
The return value or values may be explicitly listed in the "return" statement. Each expression must be single-valued and assignable to the corresponding element of the function's result type.
In your first example Reader has methods with pointer receiver, so only a pointer to Reader (that is *Reader) implements the IReader interface. So you have to return &Reader{}.
If your function has a return type of a concrete type, you have to return a value of that exact concrete type, you can't return a value of a pointer to that type.
When the return type is a Reader
func NewReader() Reader {
return &Reader{} // cannot use &Reader literal (type *Reader) as type Reader in return argument
}
you cannot use a pointer to a Reader type in place of a Reader type. The reason being they are just not of the same type.
When you use an interface like IReader as a return type as in
func NewReader() IReader {
return &Reader{}
}
it basically means that any type implementing the methods of the IReader interface will classify as a type implementing that interface and thus will be acceptable. Since the type *Reader implements the IReader type in your example, it is an acceptable return value of the NewReader function here. That means if I introduce a new type which implements this interface, such as,
type dummy int
func (d dummy) GetCount() int {
return d
}
func (d dummy) IncreaseCount() {
fmt.Println("Increased count: %d", d)
}
then I can do something like
func NewReader() IReader {
var d dummy
d = 5
return d
}
and it would still work. The underlying type of this returned value on checking using the reflect package will be dummy.

Repeat a Retrofit2.0 api-call based on the server response

Using Retrofit2 (Ver: 2.3.0), OkHTTP3 (Ver: 3.9.0) with RxJava2 (Ver: 2.0.0)
Scenario of a rest api call
Observable<ServerResponse> backendService.isUserVerified("someuserName")
which returns a 200 Ok HTTP
Expected Success Response JSON POJO if user is verified
{
user: "someUserName",
isVerified: "yes"
}
Expected Success Response JSON POJO if user is not verified
{
user: "someUserName",
isVerified: "no"
}
Following is code I am trying to implement
backendService.isUserVerified("someuserName")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//Want to add a flatmap (or some other operator)
.flatmap(new Function<ServerResponse>, ObservableSource<?>>(){
#Override
public ObservableSource<?> apply(ServerResponse serverResponse) throws Exception {
if(0 != serverResponse.getisVerified.compareToIgnoreCase("yes")) {
return Observable.error(new CustomException());
}
return //current observable.
}
.retryWhen(mRetryHandler)
.subscribeWith(observer);
The intent is to throw a custom exception if verified == no so that retryWhen() operator can pitch in to repeat the call chain, else want to proceed through the chain till subscribe().
Any pointers / help ?
You can just use doOnNext rather than flatmap:
backendService.isUserVerified("someuserName")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//we can throw an exception if the user is not verified or keep the response as it is otherwise
.doOnNext(serverResponse -> {
if(0 != serverResponse.getisVerified.compareToIgnoreCase("yes"))
{
throw new CustomException();
}
})
.retryWhen(mRetryHandler)
.subscribeWith(observer);
The doOnNext operator just performs a function with the emitted item without changing it. You just want to throw an error in a specific case based on the item and otherwise not to change it so it's an appropriate operator to use. As you don't change threads before the doOnNext operator or after it, before using the item in the next operator you know it will throw the exception BEFORE continuing in case it should throw it.
Here's an example from the linked documentation of the operator:
Observable.just(1, 2, 3)
.doOnNext(new Action1<Integer>() {
#Override
public void call(Integer item) {
if( item > 1 ) {
throw new RuntimeException( "Item exceeds maximum value" );
}
}
}).subscribe(new Subscriber<Integer>() {
#Override
public void onNext(Integer item) {
System.out.println("Next: " + item);
}
#Override
public void onError(Throwable error) {
System.err.println("Error: " + error.getMessage());
}
#Override
public void onCompleted() {
System.out.println("Sequence complete.");
}
});
[output:]
Next: 1
Error: Item exceeds maximum value
If you want to throw an error using Observable.error(new CustomException());, you don't need to make function to return a specific object for the error and another one for the expected answer, it's an exception and will go to onError() method. Your ObservableResource<?> must return your expected answer that is retrieved in onResponse() method from Subscriber. If you throw an error using Observable.error(), your chain will be broken and error will be go to onError().
Edit
You should use retry function, because will return you ServerResponse and you can check if is valid or not. Using retryWhen, you get only the error when something goes wrong. In your case, you don't get any error, you get the answer. In this case, you don't need that flatMap
.retry(new BiPredicate<ServerResponse, Throwable>() {
#Override
public boolean test(ServerResponse serverResponse, Throwable throwable) throws Exception {
return serverResponse.getisVerified.equals("no");
}
})

Java 8: convert lambda to a Method instance with closure included

(This is difficult to search because results are all about "method reference")
I want to get a Method instance for a lambda expression for use with a legacy reflection-based API. The clousure should be included, so calling thatMethod.invoke(null, ...) should have the same effect as calling the lambda.
I have looked at MethodHandles.Lookup, but it only seems to be relevant for the reverse transform. But I guess the bind method may help to include the clousure?
Edit:
Say I have am lambda experssion:
Function<String, String> sayHello = name -> "Hello, " + name;
and I have a legacy framework (SpEL) that has an API like
registerFunction(String name, Method method)
which will call the given Method with no this argument (i.e. Method assumed to be static). So I'll need to get a special Method instance that includes the lambda logic + the clousure data.
In case you don't find an elegant way, here is the ugly way (Ideone). Usual warning when reflection is involved: may break in future releases etc.
public static void main(String[] args) throws Exception {
Function<String, String> sayHello = name -> "Hello, " + name;
Method m = getMethodFromLambda(sayHello);
registerFunction("World", m);
}
static void registerFunction(String name, Method method) throws Exception {
String result = (String) method.invoke(null, name);
System.out.println("result = " + result);
}
private static Method getMethodFromLambda(Function<String, String> lambda) throws Exception {
Constructor<?> c = Method.class.getDeclaredConstructors()[0];
c.setAccessible(true);
Method m = (Method) c.newInstance(null, null, null, null, null, 0, 0, null, null, null, null);
m.setAccessible(true); //sets override field to true
//m.methodAccessor = new LambdaAccessor(...)
Field ma = Method.class.getDeclaredField("methodAccessor");
ma.setAccessible(true);
ma.set(m, new LambdaAccessor(array -> lambda.apply((String) array[0])));
return m;
}
static class LambdaAccessor implements MethodAccessor {
private final Function<Object[], Object> lambda;
public LambdaAccessor(Function<Object[], Object> lambda) {
this.lambda = lambda;
}
#Override public Object invoke(Object o, Object[] os) {
return lambda.apply(os);
}
}
Well, lambda expressions are desugared into methods during compilation and as long as they don’t capture this (don’t access non-static members), these methods will be static. The tricky part is to get to these methods as there is no inspectable connection between the functional interface instance and its target method.
To illustrate this, here the simplest case:
public class LambdaToMethod {
public static void legacyCaller(Object arg, Method m) {
System.out.println("calling Method \""+m.getName()+"\" reflectively");
try {
m.invoke(null, arg);
} catch(ReflectiveOperationException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) throws URISyntaxException
{
Consumer<String> consumer=s -> System.out.println("lambda called with "+s);
for(Method m: LambdaToMethod.class.getDeclaredMethods())
if(m.isSynthetic() && m.getName().contains("lambda")) {
legacyCaller("a string", m);
break;
}
}
}
This works smoothly as there is only one lambda expression and hence, one candidate method. The name of that method is compiler specific and may contain some serial numbers or hash codes, etc.
On kludge is to make the lambda expression serializable and inspect its serialized form:
static Method lambdaToMethod(Serializable lambda) {
for(Class<?> cl=lambda.getClass(); cl!=null; cl=cl.getSuperclass()) try {
Method m=cl.getDeclaredMethod("writeReplace");
m.setAccessible(true);
try {
SerializedLambda sl=(SerializedLambda)m.invoke(lambda);
return LambdaToMethod.class.getDeclaredMethod(sl.getImplMethodName(),
MethodType.fromMethodDescriptorString(sl.getImplMethodSignature(),
LambdaToMethod.class.getClassLoader()).parameterArray());
} catch(ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
} catch(NoSuchMethodException ex){}
throw new AssertionError();
}
public static void main(String[] args)
{
legacyCaller("a string", lambdaToMethod((Consumer<String>&Serializable)
s -> System.out.println("first lambda called with "+s)));
legacyCaller("a string", lambdaToMethod((Consumer<String>&Serializable)
s -> System.out.println("second lambda called with "+s)));
}
This works, however, serializable lambdas come at a high price.
The simplest solution would be to add an annotation to a parameter of the lambda expression to be found when iterating over the methods, however, currently, javac doesn’t store the annotation properly, see also this question about this topic.
But you may also consider just creating ordinary static methods holding the code instead of a lambda expression. Getting a Method object for a method is straight-forward and you still can create a functional interface instance out of them using method references…
Since the question mentions SpEL specifically (and I found the question when also working with SpEL), an alternative way to add a custom function to the evaluation context without using Method references is to add a custom MethodResolver (javadoc, GitHub) to the StandardEvaluationContext. A benefit of this approach is that one can add both static and non-static methods to the evaluation context using it, where only static methods could be added using the registerFunction approach.
The code to add a custom MethodResolver to the StandardEvaluationContext is fairly straightforward. Below is an executable example showing how to do so:
public static void main(String[] args) throws Exception {
Function<String, String> sayHello = name -> "Hello, " + name;
// The evaluation context must have a root object, which can be set in the StandardEvaluationContext
// constructor or in the getValue method of the Expression class. Without a root object, the custom
// MethodResolver will not be called to resolve the function.
Object rootObject = new Object();
StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(rootObject);
// Add the custom MethodResolver to the evaluation context that will return a MethodExecutor that
// Spring can use to execute the sayHello function when an expression contains "sayHello('<any string>')".
standardEvaluationContext.addMethodResolver((context, targetObject, methodName, argumentTypes) -> {
MethodExecutor methodExecutor = null;
if (methodName.equals("sayHello")
&& argumentTypes.size() == 1
&& String.class.isAssignableFrom(argumentTypes.get(0).getObjectType())
) {
methodExecutor = (innerContext, target, arguments) -> {
final String name = arguments[0].toString();
return new TypedValue(sayHello.apply(name));
};
}
return methodExecutor;
});
// Create an expression parser, parser the expression, and get the evaluated value of the expression.
SpelExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("sayHello('World!')");
String expressionValue = expression.getValue(standardEvaluationContext, String.class);
// Output the expression value, "Hello, World!", to the console.
System.out.println(expressionValue);
}
The value of the expression that was output to the console by executing the above code was:
Hello, World!
Note that when using a MethodResolver to add a function to the evaluation conext, the function should not be prefixed with a # in the expression string. This is a major difference between using the MethodResolver and using the registerFunction method to add a function to the evaluation context.
sayHello('World!') // will work!
#sayHello('World!') // will not work!
Keep this in mind if you are considering migrating an existing solution from using the registerFunction approach to using the MethodResolver approach.

How can I tell if net/http's ResponseWriter.Write() has been called?

Suppose I have a chain of net/http Handlers, and an early one responds with an HTTP error (http.StatusInternalServerError, for instance). How can I detect this in the following handlers, and avoid sending additional data to the client?
Or is this entirely the wrong approach to the problem?
http.ResponseWriter is an interface. So just compose a new instance of it:
type MyResponseWriter struct {
http.ResponseWriter
WroteHeader bool
}
func (w *MyResponseWriter) Write(b []byte) (int, error) {
w.WroteHeader = true
return w.ResponseWriter.Write(b)
}
func (w *MyResponseWriter) WriteHeader(code int) {
w.WroteHeader = true
w.ResponseWriter.WriteHeader(code)
}
And in your handlers:
//...
if w, ok := w.(*MyResponseWriter); ok && w.WroteHeader {
log.Println("Already wrote, skipping")
return
}
EDIT: Another thing to consider. Most of the time if you have a "chain" of handlers that means that a handler is called inside a handler. So if you have something like
type Handler1 struct { http.Handler }
type Handler2 struct { http.Handler }
type Handler3 struct { http.Handler }
var MyHandler http.Handler = Handler1{Handler2{Handler3{h}}}
as long as each of those call the inner handler as the last thing they do with w and r, you should be fine because then w and r won't even reach the inner handler. E.g.
func (h Handler2) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if somethingBadHappened() {
w.WriteHeader(http.StatusInternalServerError)
return
}
h.ServeHTTP(w, r) // Not called if somethingBadHappened().
}
First: a lighter-weight solution may exist.
However, if you cannot find one, consider using x/net/context to allow you to implement timeouts, deadlines, and of course, early termination of middleware chains.

Interfaces stored as value; Methods unable to update struct fields

I have a tool that I'm writing that exposes some functions that pull information out of a static database to several scripting languages that I'm embedding into the tool.
I thought; "Hey sounds like a nice use case for interfaces". So I defined an interface like so in my package scripting
type ScriptingLang interface {
RunScript(filename string) error
RunString(s string) error
Interpreter() error
Init() error
IsInit() bool
}
Then I store a map of them so I can look them up by a string defined like so in a different package.
var ScriptingLangs = make(map[string]scripting.ScriptingLang)
and a function to register them. Also some little helper functions like
func RunString(lang, s string) error {
if v, ok := ScriptingLangs[lang]; ok {
if !v.IsInit() {
v.Init()
}
return v.RunString(s)
} else {
return NoSuchLangErr
}
return nil
}
The problem that I ran into is it seams that interfaces can't have methods with pointer receivers. As a result my Lua struct that implements ScriptingLang isn't able to save it's *state because it's stored in ScriptingLangs.
I've tried updating the value stored in the map at the end of functions that save state and it didn't update the value.
To my understanding you shouldn't use pointers of interfaces so what are my options here? I would like to really keep the interfaces so I can do some neat stuff with git submodules.
A minimal example of my problem:
package main
import (
"fmt"
)
type ScriptingLang interface {
DoString(s string) error
Init() error
}
type Lua struct {
state string
}
func (l Lua) DoString(s string) error {
fmt.Printf("Doing '%v' with state '%v'\n", s, l.state)
return nil
}
func (l Lua) Init() error {
l.state = "Inited"
return nil
}
var lang ScriptingLang
func main() {
lang = Lua{}
lang.Init()
lang.DoString("Stuff")
}
If you want to mutate state, you need a pointer receiver, and your Init method doesn't have one. The fact that you're storing the value inside an interface makes no difference.
In your minimal(-ish) example, change the Init method (and any method that updates state) to have a pointer receiver, and point a pointer inside the interface and everything works:
func (l *Lua) Init() error {
l.state = "Inited"
return nil
}
...
func main() {
lang = &Lua{}
lang.Init()
lang.DoString("Stuff")
}
This article might help: http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go

Resources