LINUX.ORG.RU

А какой язык умеет так?


0

5

Возврат нескольких значений из функции [псевдокод на С]:


(double, double, int) foo()
{
    double a = 10;
    double b = 15;
    int c = 20;
    
    return (a,b,c);
}

int main(int argc, char** argv)
{
    double x, y;
    int z;

    (x,y,z) = foo();
    
    return 0;
}

P.S. Как сделать подобное в Си я прекрасно знаю. Интересуют языки, которые могут сделать все именно так, как это описано в псевдокоде.

★★★★★

Последнее исправление: trex6 (всего исправлений: 1)

Ответ на: комментарий от schizoid

Интересный способ, но насколько знаю, нужно ещё выдерживать выравнивания, либо делать memcpy вместо простого присваивания при (рас)паковке. (Например, если первый элемент в кортеже - char, обращение к второму элементу - double - по нечётному адресу, не на всех архитектурах проца пройдёт успешно)

Krieger_Od ★★
()

ocaml (как в F#)

 let f a = a, 2, 3, "four" in let f2 = let a,b,c,_ = f "one" ... 

nCdy
()

python такое умеет, если быть более точным, он возвращает кортеж элементов. Благодаря динамической типизации типы могут быть произвольными....

BattleCoder ★★★★★
()

Примерно вот так

def foo:
    a = 10
    b = 15
    c = 20
    return a,b,c

if __name__=='__main__':
    result = foo()
    print(result)
    # выведет что-то вроде (10,15,20)

Если нужно именно double, лучше точку в конце указывать.. например, 10.0, 15.0

BattleCoder ★★★★★
()
Ответ на: комментарий от anonymous

Tuple: 'a * 'b * ...

Да, этот тип выводится статически

ну да, конечно это имитация values из CL, которая ведёт себя по-другому. Другое дело, что в силу статики самого F#, такая имитация множественных значений вполне приемлема...

pseudo-cat ★★★
()
Ответ на: комментарий от trex6

trex6

но количество структур на один проект конечно.

а сколько в штуках?

drBatty ★★
()
Ответ на: комментарий от aedeph_

gfortran, походу, просто игнорирует этот intent :)

А вот что делает нормальный компилятор:

$ cat test.f90
program test
  implicit none

  integer :: x
  x=1
  call foo(x)
  print*, x

contains
  subroutine foo(x)
    integer, intent(out) :: x

  end subroutine foo

end program test
$ ifort test.f90
test.f90(10): warning #6843: A dummy argument with an explicit INTENT(OUT) declaration is not given an explicit value.   [X]
  subroutine foo(x)
-----------------^
yvv ★★☆
()
Ответ на: комментарий от yvv

ifort? Это всего лишь ворнинг, да еще и рутина не настоящая, а замыкание. gfortran не игнорирует, он просто не использует входное значение (как если бы переменная была только инициализирована).

С чего бы компилятор считал это ошибкой мне не ясно. Вот intent(in) попробовать переписать - это error.

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

aedeph_ ★★
()
Ответ на: комментарий от aedeph_

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

Это никто не запрещает.

yvv ★★☆
()
Ответ на: комментарий от aedeph_

Очевидно, для этого компилятор и выдаёт предупреждение, когда есть intent(out), а значение не присвоено.

Конкретно в этом случае, кстати, никаких предупреждений нет. И мусора тоже никакого нет. Т.е., компилятор всё-таки достаточно умно ситуацию обрабатывает.

yvv ★★☆
()

Язык Go так умеет, например:

package main //нужно для main

import (
            fmt "fmt" //Printf
            "os"         //os.Exit, os.Args(i)
            "flag"      //разбор опций командной строки типа getopt,но проще
          )

func foo1()(a float64,b float64, c int) 
//а,b,c -- именованные возвращаемые параметры. 
// Как в open -- возвращает 2 значения, дескриптор файла и ошибку
{
    a = 10
    b = 10
    c = 20
    return // вернуть все 3 значения
}

func foo2()(float64,float64,int) {
  c := 20 // аналогично auto c = 20. Вывод типов, c типа int потому что 20 - int
  return (10,10,c)
}
/* остальные варианты foo -- аналогично */

func  main() { 
  //даже если нужны аргументы. Cм. os.Args или getopt-like модуль flag 
 /** вариант 1*/
  var x,y float64
  var z int
  
  x,y,z = foo() 

 /** вариант 2, без описания переменных */
 x,y,z := foo()
 
 //os.Exit(0) //не нужен по умолчанию
}

anonymous
()

А какой язык умеет так?

Вы так спрашиваете, будто это офигеть какая важная фича...

anonymous
()
Ответ на: комментарий от anonymous

Я об этом спрашиваю потому, что мне стало интересно.

trex6 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.