-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mergeMap/flatMap and Java 8 type inference #1550
Comments
Observable.from(1, 2, 3, 4).mergeMap(i -> {
if (i < 3) {
return Observable.just("value_" + i);
} else {
return Observable.empty();
}
}).forEach(System.out::println); |
It also correctly infers it is a String: Observable<String> mergeMap = Observable.from(1, 2, 3, 4).mergeMap(i -> {
if (i < 3) {
return Observable.just("value_" + i);
} else {
return Observable.empty();
}
}); |
@benjchristensen static class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
savedUser()
.mergeMap(Observable::just, e -> fetchUser(), Observable::empty)
.forEach(user -> System.out.println(user.name));
}
static Observable<User> savedUser() {
return Observable.error(new IllegalStateException("there are no saved users"));
}
static Observable<User> fetchUser() {
return Observable.just(new User("Adel", 13));
} |
This code compiles and runs for me: import rx.Observable;
public class Issue1550 {
static class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
savedUser()
.mergeMap(Observable::just, e -> fetchUser(), Observable::empty)
.forEach(user -> System.out.println(user.name));
}
static Observable<User> savedUser() {
return Observable.error(new IllegalStateException("there are no saved users"));
}
static Observable<User> fetchUser() {
return Observable.just(new User("Adel", 13));
}
} It outputs:
|
Ah interesting, it works in Eclipse, but not from command line.
|
Fixes issue ReactiveX#1550
Fixes issue ReactiveX#1550
I believe this is now fixed as of #1558. If you can confirm against the branch, please do. Reopen if there are still issues. |
@benjchristensen I don't have the rights to reopen the issues
I don't really think this is an issue, because expanding the method ref as a |
@benjchristensen I'm using Oracle JDK on Ubuntu 14.04
|
@zsxwing You're good at figuring this kind of stuff out, so is there anything we should be doing differently here, or is this just a weakness of Java 8? |
@benjchristensen actually, I know little about Java type inference. I try the following codes and it works: import rx.Observable;
import rx.functions.*;
public class Issue1550 {
static class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
Func0<Observable<User>> empty = () -> Observable.empty();
Func1<User, Observable<User>> just = (User user) -> Observable.just(user);
savedUser().flatMap(
just,
e -> fetchUser(),
empty)
.forEach(user -> System.out.println(user.name));
}
static Observable<User> savedUser() {
return Observable.error(new IllegalStateException("there are no saved users"));
}
static Observable<User> fetchUser() {
return Observable.just(new User("Adel", 13));
}
} So I guess it's a weakness of Java type inference. Looks we have to write a temp variable to tell the compiler type information. |
The following codes work, too: import rx.Observable;
import rx.functions.*;
public class Issue1550 {
static class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
Func0<Observable<User>> empty = Observable::empty;
Func1<User, Observable<User>> just = Observable::just;
savedUser().flatMap(
just,
e -> fetchUser(),
empty)
.forEach(user -> System.out.println(user.name));
}
static Observable<User> savedUser() {
return Observable.error(new IllegalStateException("there are no saved users"));
}
static Observable<User> fetchUser() {
return Observable.just(new User("Adel", 13));
}
} |
Java 8 type inference has some weaknesses, and javac won't compile code that will compile just fine in Eclipse 4.4. Based on some comments in lambda-dev, those javac shortcommings won't be fixed until Java 9. |
so @akarnokd is it your assessment that there is not anything better we can do with the RxJava APIs and it's just up to the language/compiler itself? |
Java 6 and 7 developers would need the full covariance in the parameter types and only Java 8 non-Eclipse developers have to do workarounds such as above. Besides, the Stream.flatMap has full covariance in its signature:
So it is either lambda workarounds for Java 8 devs or unchecked casting for Java 6/7 to bypass the lack of variance. |
I'm considering this "as good as it can get" then since our <R> Observable<R> flatMap(Func1<? super T, ? extends Observable<? extends R>> func) Thanks @akarnokd for the insight. |
@adelnizamutdinov I don't see a new issue created, so wanted to pick it up here.
You said this:
Can you elaborate?
The text was updated successfully, but these errors were encountered: