访问匿名之外的变量 class
Accessing variables outside of anonymous class
我目前正在使用 IBM Watson java SDK 中包含的 IBM 语音转文本服务。我正在尝试将成绩单字符串设置为等于结果的成绩单。但是,当我 运行 此代码时,不会打印该值。我不确定为什么会这样,或者如何解决这个问题。任何帮助,将不胜感激。我曾尝试在 main 方法之外使用带有静态变量的外部 setter,但我没有成功。
final String[] transcript = {""};
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
@Override
public void onTranscription(SpeechRecognitionResults speechResults) {
for(int i = 0; i < speechResults.getResults().size(); i++){
transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
}
}
});
System.out.println(transcript[0]);
您可以将数组转录本包装在一个 class 中,它有自己的处理程序或使用者(一种处理异步请求的方法)。
像这样:
import java.util.function.Consumer;
public class ArrayWrapper {
private Consumer consumer;
private Object [] array;
public ArrayWrapper(int size) {
this.array = new Object [size];
}
public void addConsumer(Consumer consumer) {
this.consumer = consumer;
}
public void add(Object o, int index) {
array[index] = o;
consumer.accept(o);
}
public Object [] get() {
return array;
}
}
然后您可以在 Consumer 中实现您的逻辑:
ArrayWrapper transcript = new ArrayWrapper(1);
transcript.addConsumer(new Consumer() {
@Override
public void accept(Object o) {
// perform your operations
System.out.println(o);
}
});
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
@Override
public void onTranscription(SpeechRecognitionResults speechResults) {
for(int i = 0; i < speechResults.getResults().size(); i++){
String newTranscript = transcript.get()[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
transcript.add(newTranscript, 0);
}
}
});
这只是一个示例,但想法是您必须在回调中使用一个函数,一些信号告诉您何时在回调中完成循环或类似的东西。
编辑:
或者您可以通过更简单的方式执行此操作(无需任何额外的 classes):
final String[] transcript = {""};
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
//your operations
System.out.println(s);
}
};
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
@Override
public void onTranscription(SpeechRecognitionResults speechResults) {
for(int i = 0; i < speechResults.getResults().size(); i++){
transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
consumer.accept(transcript[0]);
}
}
});
}
问题是recognizeUsingWebSocket
是一个异步调用。因此,当您执行此操作时,System.out.println(transcript[0]
您对 IBM Watson 服务的调用很可能尚未完成。
当回调方法onTranscription
被触发时,您将知道异步操作已完成。因此,在该方法内部和 for
循环之后,您可以确定 transcript
数组中已经有一些值。在那里,你可以对结果做任何你想做的事情。
如果您想在回调之外使用转录值,最简单的解决方案是在 class 中定义一个新方法并在 onTranscript
回调结束时调用它。
...
public void onTranscriptReceived(String[] transcript) {
// Do whatever you want
}
...
final String[] transcript = {""};
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
@Override
public void onTranscription(SpeechRecognitionResults speechResults) {
for(int i = 0; i < speechResults.getResults().size(); i++){
transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
}
onTranscriptReceived(transcript);
}
});
还有许多其他解决方案可以处理异步调用。就个人而言,我喜欢 ReactiveX libraries, in your case RxJava specifically。可能需要一些时间来学习,但绝对值得。
我目前正在使用 IBM Watson java SDK 中包含的 IBM 语音转文本服务。我正在尝试将成绩单字符串设置为等于结果的成绩单。但是,当我 运行 此代码时,不会打印该值。我不确定为什么会这样,或者如何解决这个问题。任何帮助,将不胜感激。我曾尝试在 main 方法之外使用带有静态变量的外部 setter,但我没有成功。
final String[] transcript = {""};
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
@Override
public void onTranscription(SpeechRecognitionResults speechResults) {
for(int i = 0; i < speechResults.getResults().size(); i++){
transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
}
}
});
System.out.println(transcript[0]);
您可以将数组转录本包装在一个 class 中,它有自己的处理程序或使用者(一种处理异步请求的方法)。
像这样:
import java.util.function.Consumer;
public class ArrayWrapper {
private Consumer consumer;
private Object [] array;
public ArrayWrapper(int size) {
this.array = new Object [size];
}
public void addConsumer(Consumer consumer) {
this.consumer = consumer;
}
public void add(Object o, int index) {
array[index] = o;
consumer.accept(o);
}
public Object [] get() {
return array;
}
}
然后您可以在 Consumer 中实现您的逻辑:
ArrayWrapper transcript = new ArrayWrapper(1);
transcript.addConsumer(new Consumer() {
@Override
public void accept(Object o) {
// perform your operations
System.out.println(o);
}
});
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
@Override
public void onTranscription(SpeechRecognitionResults speechResults) {
for(int i = 0; i < speechResults.getResults().size(); i++){
String newTranscript = transcript.get()[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
transcript.add(newTranscript, 0);
}
}
});
这只是一个示例,但想法是您必须在回调中使用一个函数,一些信号告诉您何时在回调中完成循环或类似的东西。
编辑:
或者您可以通过更简单的方式执行此操作(无需任何额外的 classes):
final String[] transcript = {""};
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
//your operations
System.out.println(s);
}
};
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
@Override
public void onTranscription(SpeechRecognitionResults speechResults) {
for(int i = 0; i < speechResults.getResults().size(); i++){
transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
consumer.accept(transcript[0]);
}
}
});
}
问题是recognizeUsingWebSocket
是一个异步调用。因此,当您执行此操作时,System.out.println(transcript[0]
您对 IBM Watson 服务的调用很可能尚未完成。
当回调方法onTranscription
被触发时,您将知道异步操作已完成。因此,在该方法内部和 for
循环之后,您可以确定 transcript
数组中已经有一些值。在那里,你可以对结果做任何你想做的事情。
如果您想在回调之外使用转录值,最简单的解决方案是在 class 中定义一个新方法并在 onTranscript
回调结束时调用它。
...
public void onTranscriptReceived(String[] transcript) {
// Do whatever you want
}
...
final String[] transcript = {""};
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
@Override
public void onTranscription(SpeechRecognitionResults speechResults) {
for(int i = 0; i < speechResults.getResults().size(); i++){
transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
}
onTranscriptReceived(transcript);
}
});
还有许多其他解决方案可以处理异步调用。就个人而言,我喜欢 ReactiveX libraries, in your case RxJava specifically。可能需要一些时间来学习,但绝对值得。