Действительный код Java, который НЕ является действительным кодом Groovy?

Учитывая ваш вариант использования, в котором вы всегда проверяете [113].<prop> == newthing.<prop>, вы можете поднять это немного больше, добавив:

mutating func replaceOrAppend<Value>(_ item: Element, 
                                     firstMatchingKeyPath keyPath: KeyPath<Element, Value>)
    where Value: Equatable
{
    let itemValue = item[keyPath: keyPath]
    replaceOrAppend(item, whereFirstIndex: { [110][keyPath: keyPath] == itemValue })
}

Затем вы можете использовать его как:

[111 ]

И, конечно, если вы делаете это много, вы можете продолжать подниматься и подниматься.

protocol Identifiable {
    var id: Int { get }
}

extension Student: Identifiable {}

extension Array where Element: Identifiable {
    mutating func replaceOrAppendFirstMatchingID(_ item: Element)
    {
        replaceOrAppend(item, firstMatchingKeyPath: \.id)
    }
}

array.replaceOrAppendFirstMatchingID(alice0) // [alice1, alice0]
24
задан Zach Lysobey 22 January 2014 в 22:06
поделиться

5 ответов

Here is a list of items that are valid Java 6, but not valid Groovy 1.6. This isn't a complete list, but I think it covers most of the cases. Some of these are permitted by later Groovy versions as noted below.

(By the way, I think you should note that non-static initialization blocks DO work in Groovy.)

Any inner class declaration in Groovy 1.6 (1.7 added inner classes):

including static,

public class Outer{
  static class Inner{}
}

non-static,

public class Outer{
  class Inner{}
}

local classes,

public class Outer{
  public static void main(String[] args) {
    class Local{}  
  }
}

and anonymous classes

java.util.EventListener listener=new java.util.EventListener(){};

Using Groovy keywords as variables won't work in any Groovy version:

int def;
int in;
int threadsafe;
int as;

Java array initialization

String[] stuff=new String[]{"string"};
int[] array={1,2,3};

Use the Groovy array-literal format by changing {...} to [...].

Using dollar signs in strings where what follows isn't a valid expression

String s="$$";
String s="$def";
String s="$enum";
String s="$;";
String s="$\\";
//etc.

More than one initializer in a for loop

for (int i=0, j=0; i < 5; i++) {}

More than one increment in a for loop

int j=0;
for (int i=0; i < 5; i++,j++) {}

Breaking up some expressions using newlines

int a= 2 
/ 2 
;

Hint: use a backslash line-continuation in Groovy

int a= 2 \
/ 2 \
;

Ending switch with a case that has no body

switch(a){
  case 1:
}

Having a default in a switch with no body

Applies in both cases where default is at the end

int a=0;
switch(a){
    default:
}

or somewhere in the middle

switch(a){
    default:
    case 1:
        break;
}

Annotations with lists

@SuppressWarnings({"boxing","cast"})

Hint: use Groovy list-literal syntax instead:

@SuppressWarnings(["boxing","cast"])

Native method declaration

public native int nativeMethod();

**Class per enum in 1.6 (valid in later Groovy versions) **

public enum JavaEnum{
  ADD{
    public String getSymbol(){ return "+"; }
  };
  abstract String getSymbol();
}

Do loop

do{
  System.out.println("stuff");
}while(true);

Equality

While technically == is valid Groovy and Java, it's semantically different. It's one of the reasons you can't rely on just compiling Java as Groovy without changes. Worse, it might seem to work sometimes due to Java string interning.

The example was too long to add to an existing answer, but the point is that Java code that's syntatically valid as Groovy might behave differently at runtime.

To get the same result as Java's x == y for two not-null objects you need x.is(y) in Groovy. x == y is valid Groovy, it just does something different.

The Groovy documentation has a more detailed and broader list of differences.

33
ответ дан 28 November 2019 в 23:04
поделиться

Хорошо, вот одна точка:

int[] i = { 0, 1, 2 };

Это - хороший синтаксис в Java, плохо в отличном.

Я не думаю, что Вы хотите предположить, что любой данный код Java будет эквивалентен в отличном. Этот сайт описывает некоторые различия, которые включают вещи как основные как == не значение того же самого на обоих языках. Кроме того, статическая инициализация массива отличается, и нет никаких анонимных внутренних классов.

Это компилирует прекрасный в Java 1.6

public class Test2 {
    int[] i = { 0, 1, 2 };

    private class Class1 {
        public void method1() {
            if (i[2] == 2) {
                System.out.println("this works");
            }
        }
    }

    public void method1() {
        Class1 class1 = new Class1();
        class1.method1();
    }
}

Но является настолько неправильным в Groovy. Это дает следующие ошибки в Groovy 1.6:

unexpected token: 1 @ line 2, column 14.

Class definition not expected here. Possible attempt to use inner class. Inner classes not supported, perhaps try using a closure instead. at line: 4 column: 2.

При фиксации тех вещей это действительно печатает то, что Вы ожидаете, все же.

При поиске более новых проблем синтаксиса языка, как дженерики или аннотации, Groovy поддерживает обоих из тех, хотя не полностью.

12
ответ дан 28 November 2019 в 23:04
поделиться

Все я могу думать на данный момент:

  • int def;
  • String s = "$$";
1
ответ дан 28 November 2019 в 23:04
поделиться

Нестатические блоки инициализации:

class Foo {
  Integer x;   
  { x = 1; }
}

ОБНОВЛЕНИЕ: Это - на самом деле действительный код Groovy.

0
ответ дан 28 November 2019 в 23:04
поделиться

Многомерные массивы, размер которых не указан.

def x=new Object[5][];  // ERROR: expression expected 

def x=new Object[5][2]; // this works
3
ответ дан 28 November 2019 в 23:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: