I have the following code snippet where Func0
and Action1
are used.
Observable.defer(new Func0<Observable<String>>() { @Override public Observable<String> call() { try { return Observable.just(Database.readValue()); } catch(IOException e) { return Observable.error(e); } }) .subscribe(new Action1<String>() { @Override public void call(String result) { resultTextView.setText(result); } } }
But I am just wondering what is the difference between them. I understand that the number means the number of parameters i.e. Func0
has no parameters and Action1
has 1 parameters.
However, how would you know which one to use? Should I use Action
or Func
.
What is the purpose of the call
method?
Many thanks for any suggestions,
2 Answers
Answers 1
The short answer; You'll know based on what method you're calling.
First lets take a look at the two methods you're trying to use:
Observable.defer Returns an Observable that calls an Observable factory to create an Observable for each new Observer that subscribes. That is, for each subscriber, the actual Observable that subscriber observes is determined by the factory function.
Parameters: observableFactory the Observable factory function to invoke for each Observer that subscribes to the resulting Observable
Returns: an Observable whose Observers' subscriptions trigger an invocation of the given Observable factory function
public final static <T> Observable<T> defer(Func0<Observable<T>> observableFactory)...
Observable.subscribe Subscribes to an Observable and provides a callback to handle the items it emits.
Parameters: onNext the Action1 you have designed to accept emissions from the Observable
Returns: a Subscription reference with which the Observer can stop receiving items before the Observable has finished sending them
public final Subscription subscribe(final Action1<? super T> onNext)...
What you see above are two examples of Higher-order functions or implementations of the Strategy Pattern which each accept a different strategy format.
In the case of defer
you a providing a way to create a new Observable
with no initial input provided. A Func0 is requested because it has that format (where R
is an Observable<String>
):
public interface Func0<R> extends Function, Callable<R> { @Override public R call(); }
In the case of subscribe
you are providing a way to accept a value from an observable. The best interface to represent this would be an Action1 (where T1
is a String
)
public interface Action1<T1> extends Action { public void call(T1 t1); }
When you write new Action1<>() {...}
or new Func0<>() {...}
you are creating what is known as an Anonymous Class. You are defining in place what happens when the method Action1.call
or Func0.call
are invoked.
Your questions:
how would you know which one to use? Should I use Action or Func.
It depends on the needs of your application. Read through the docs and see which method best suits your needs. Depending on the method you choose you will have to implement the interface it specifies in the method signature.
What is the purpose of the call method?
This is the name of method in the strategy/interface required by the higher order function which you are using. You will know the name by looking at the interface definition. It is only by chance that each interface declares a method named call
. One could have easily been titled foo
and the other bar
.
Answers 2
Look at their definition:
interface Func0<R> { R call(); } interface Action1<T> { void call(T t); }
The Func0
provides data whereas Action1
consumes data. These are dual functionalities and you can't mistake the two.
0 comments:
Post a Comment