如何编写一个可以接受文字数组的通用函数

huangapple go评论77阅读模式
英文:

How to write a generic function which accepts arrays of literals

问题

我无法将类型为int[]float[]等的值提供给通用函数。我会收到错误,基本上说float[]是错误的类型,而函数实际接受的是Float[]

这里有一个我写的方法示例,我试图为它提供像new int[]{0,1}(在库的其他地方创建的)这样的值。

private static <T> JSONArray encodeArray(T[] array) {
    JSONArray arr = new JSONArray();
    Collections.addAll(arr, array);
    return arr;
}

甚至有可能编写函数签名以接受这些字面数组吗?

我可以转到调用站点,将float[]转换为Float[],但我也不知道该如何做到这一点。

英文:

I am unable to provide values of type int[], float[], etc. to a generic function. I get errors that say basically that float[] is the wrong type and Float[] is what the function actually takes.

Here's an example of a method I wrote, and I'm trying to give it values like new int[]{0,1} (created in library somewhere else).

private static &lt;T&gt; JSONArray encodeArray(T[] array) {
    JSONArray arr = new JSONArray();
    Collections.addAll(arr, array);
    return arr;
}

Is it even possible to write my function signature to accept these arrays of literals?

I could go to the call site, and do a conversion of float[] to Float[], but I don't know how to do that either.

答案1

得分: 0

接受一个通用数组的方法。

public <T> void printArray(T[] array){
    for (T element: array){
        System.out.println(element);
    }
}

您不能在通用函数中使用基本数据类型。当通用代码被编译时,在上面的示例中会得到 Object[] 作为实现类型。由于 int[] 和 byte[] 等不扩展 Object[],即使涉及的代码完全相同(再次强调,通用不是模板),您也不能将它们互换使用。

英文:

The method which accepts a generic array.

public &lt;T&gt; void printArray(T[] array){
        for (T element: array){
            System.out.println(element);
        }
    }

You can't use primitives in generic functions. When generic are compiled, you end up with Object[] in the above example as the implementing type. As int[] and byte[] etc, do not extend Object[] you cannot use them interchangeably even if the code involved would be identical (again generics are not templates)

答案2

得分: 0

在@Max-Reshetnyk的解决方案基础上,最好是检查ArrayList中能够帮助你add或者remove元素的方法。由于原始数据类型不适用于泛型,你应该使用其相应类型进行AutoBox,然后再使用泛型。

例如:

class Main {
  public static void main(String[] args) {
    Integer[] x = new Integer[1];
    x[0] = 1;
    printArray(x); 
  }

  public static <T> void printArray(T[] array){
        for (T element: array){
            System.out.println(element);
        }
    }
}
英文:

Add on the solution from @Max-Reshetnyk, It is better if you check ArrayList for methods that help you add or remove... elements. Since primitive types are not meant to be used with generics, you should AutoBox them with their respective types and then use generics.

For instance:

class Main {
  public static void main(String[] args) {
    Integer[] x = new Integer[1];
    x[0] = 1;
    printArray(x); 
  }

  public static &lt;T&gt;  void printArray(T[] array){
        for (T element: array){
            System.out.println(element);
        }
    }
}

答案3

得分: 0

是否有可能编写我的函数签名来接受这些数组字面量?

可以,但参数类型必须是Object,因为这是“原始数组”和“引用数组”的唯一共同超类(例如,它不能是Object[],因为原始数组不是Object[]的子类)。(所有数组都实现了一些接口,但我暂时会忽略它们。)不幸的是,这意味着您将失去类型安全性,因为编译器无法在编译时对传递非数组类型的情况进行错误提示。

要对这个Object值执行数组操作,您需要使用反射辅助类java.lang.reflect.Array中的方法。因此,您可以像这样做:

import java.lang.reflect.Array;

// ...

private static JSONArray encodeArray(Object array) {
    JSONArray arr = new JSONArray();
    for (int i = 0, n = Array.getLength(array); i < n; i++) {
        arr.add(Array.get(array, i)); // 原始类型会自动封装
    }
    return arr;
}
英文:

> Is it even possible to write my function signature to accept these
> arrays of literals?

It is possible, but the parameter type will have to be Object, because that is the only common superclass of "arrays of primitives" and "arrays of references" (e.g. it can't be Object[] since arrays of primitives are not subclasses of Object[]). (There are also some interfaces that all arrays implement, but I will ignore those for now.) Unfortunately, this means that you will lose type safety as the compiler will not be able to give an error at compile time if someone passes a non-array type in.

To do array operations on this Object value, you will need to use the methods in the reflection helper class java.lang.reflect.Array. So you can do something like this:

import java.lang.reflect.Array;

// ...

private static JSONArray encodeArray(Object array) {
    JSONArray arr = new JSONArray();
    for (int i = 0, n = Array.getLength(array); i &lt; n; i++) {
        arr.add(Array.get(array, i)); // primitives are automatically wrapped
    }
    return arr;
}

huangapple
  • 本文由 发表于 2020年10月20日 01:43:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/64432600.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定