假设我有一个功能
def request(url: String): Future[String]
需要编写一个函数
def requestFirst(urls: List[String]): Future[String]
按顺序调用request(url)直到它成功完成(在这种情况下返回成功的值)或所有url的请求失败(在这种情况下返回所有失败)。
如何在Scala中完成?
答案 0 :(得分:2)
/* cpm.c
Useful functions for Workshop E
*/
#include"cpm.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#define BUFFERSIZE 4096
void oops(char *, char *);
unsigned char bitmap[12];
struct CPMdirent directory[64];
int toggle_bit(int block) /*directory - initilise disk*/
{
int elem=block/8;
int pos=block%8;
int mask=1<<pos;
bitmap[elem]^=mask;
return bitmap[elem]&mask;
}
int block_status(int block)
{
int elem=block/8;
int pos=block%8;
int mask=1<<pos;
return bitmap[elem]&mask;
}
int main(int argv, char *av[])
{
int choice = 0;
int input_fd, output_fd, n_chars, status;
char buffer[BUFFERSIZE];
char cwd[1024];
char file_name[9];
FILE *fptr;
struct dirent *dir;
DIR *dp;
do
{
printf("Please choose a task (enter the number)\n");
printf("1. Intialise Disk\n");
switch(choice)
{
/*Intialising the disk (store directory in arrays)*/
case 1:
printf("~~~~~~~~~~~~ Initialising the disk ~~~~~~~~~~~~\n");
toggle_bit(0);
directory[0].usercode;
directory[0].filename[9];
directory[0].filetype[4];
directory[0].extent;
directory[0].blockcount;
directory[0].blocks[16];
printf("\nDisk sucessfully initialised.\n");
break;
}
while(choice != 8);
}
void oops(char *s1, char *s2)
{
fprintf(stderr,"Error: %s ", s1);
perror(s2);
exit(1);
}
OR
def requestFirst(urls: List[String]): Future[String] = {
val default: Future[String] = Future.failed(new scala.Exception("all failed"))
urls.foldLeft(default)((prevFuture, currentUrl) => {
prevFuture fallbackTo (request(currentUrl))
})
}
答案 1 :(得分:0)
这是我根据@ parnav-shukla答案提出的:
def requestFirst(urls: List[String]): Future[String] = {
def requestFirstInternal(urlSubset: List[String], errors: Seq[String]): Future[String] = {
if(urlSubset.isEmpty) {
Future.failed(new Exception(errors.mkString("\n")))
} else {
request(urlSubset.head) recoverWith { t =>
requestFirstInternal(urlSubset.tail, errors ++ Seq(t.getMessage))
}
}
}
requestFirstInternal(urls, Seq.empty)
}