Perl 6의 함수 서명

11490 단어

사인도 대상이에요.

> sub a($a, $b) {};
> &a.signature.perl.say
:($a, $b)
> my $b = -> $a, $b {};
> $b.signature.perl.say
:($a, $b)

서명은 Perl 6의 다른 모든 것과 같은 객체입니다.모든 Callable 형식에 서명이 있고 .signature 방법으로 얻을 수 있습니다.
class Signature { ... }

서명은 코드 대상 매개 변수 목록의 정적 설명입니다.즉, 서명은 코드나 함수에 어떤 매개 변수와 몇 개의 매개 변수를 전달해서 호출해야 하는지를 설명합니다.
매개변수를 서명에 전달하여 Capture에 포함된 매개변수를 서명에 바인딩합니다.

서명 문자 크기


서명은 서브루틴과 방법명 뒤에 있는 괄호에 나타나고 Blocks에 있는 -> 또는 , ( my 의 입력에 나타나거나, 사칭으로 시작하는 것을 단독 항목으로 한다.
sub f($x) { }
#    ^^^^ sub f  
method x() { }
#       ^^   x  
my $s = sub (*@a) { }
#           ^^^^^  

for @list -> $x { }
#            ^^    block  

my ($a, @b) = 5, (6,7,8);
#  ^^^^^^^^  

my $sig = :($a, $b);
#          ^^^^^^^^  

sub f(&c:(Int)){}
sub will-work(Int){}
sub won't-work(Str){}
f(&will-work);
f(&won't-work); # fails at runtime
f(-> Int { 'this works too' } );

매개 변수 구분자


0 。

:($a, @b, %c)
sub add ($a, $b) { $a + $b }

, 。 , self, 。

:($a: @b, %c)  #  

class Foo {
    method whoami ($me:) {
        "Well I'm class $me.^name(), of course!"
    }
}

say Foo.whoami; # Well I'm class Foo, of course!

유형 구속조건


( Any ).이것들은 함수가 허용하는 입력을 제한하는 데 사용할 수 있다.

:(Int $a, Str $b)
sub divisors (Int $n) { $_ if $n %% $_ for 1..$n }
divisors 2.5; # !!! Calling 'divisors' will never work with argument types (Rat)

익명의 매개 변수도 괜찮습니다. 매개 변수가 형식 제약만 필요하다면.
:($, @, %a)         #   " ( )" 
:(Int, Positional)  #  ( )
sub baz (Str) {"Got a String"}
baz("hello");

유형 구속은 유형 캡처(type captures)일 수도 있습니다.
이러한 명목상의 유형을 제외하고, 추가 제약은 코드 블록의 형식으로 매개 변수에 추가할 수 있으며, 코드 블록은 형식 검사를 통해 실제 값을 되돌려야 한다.
sub f(Real $x where { $x > 0 }, Real $y where { $y >= $x }) { }

사실where 뒤에는 코드 블록이 필요하지 않습니다. where-block 오른쪽에 있는 모든 것은 매개 변수와 스마트하게 일치하는 데 사용됩니다.그래서 너도 이렇게 쓸 수 있다.
multi factorial(Int $ where 0) { 1 }
multi factorial(Int $x) { $x * factorial($x - 1) }

첫 번째는 간소화할 수 있어요.
multi factorial(0) { 1 }

너는 직접 글자의 양을 형식으로 사용하고 값을 익명 매개 변수에 제약할 수 있다.

구속조건 정의 값 및 정의되지 않은 값


일반적으로 유형 구속조건은 전달된 값이 올바른 유형인지만 확인합니다.
sub limit-lines (Str $s, Int $limit) {
    my @lines = $s.lines;
    @lines[0 ..^ min @lines.elems, $limit].join("
") } say (limit-lines "a
b
c
d
", 3).perl; # "a
b
c " say limit-lines Str, 3; # Uh-oh. Dies with "Cannot call 'lines';" say limit-lines "a
b", Int # Always returns the max number of lines

이런 경우, 우리는 사실 정의된 문자열만 처리하고 싶다.이렇게 하려면 :D 유형의 제약을 사용합니다.
sub limit-lines (Str:D $s, Int $limit) {
    ...
}

say limit-lines Str, 3;
# Dies with "  '$s'  ,   limit-lines  。


Str와 같은 유형의 대상을 전달하면 오류가 발생합니다.이런 실패 방식은 이전보다 더욱 좋아졌다. 왜냐하면 실패의 원인이 더욱 명확해졌기 때문이다.
정의되지 않은 유형이 하위 루틴의 유일한 의미 있는 수신값일 수도 있습니다.이것은 :U 유형의 제약을 사용하여 제약할 수 있다.예를 들어 우리는 &limit-lines를 멀티 함수로 바꾸어 :U 제약을 사용할 수 있다.
multi  limit-lines (Str $s, Int:D $limit) {
    my @lines = $s.lines;
    @lines[0 ..^ min @lines.elems, $limit].join("
"); } multi limit-lines (Str $s, Int:U $) {$s} # , say limit-lines "a
b
c", Int; # "a
b
c"

일반적인 행동을 현시적으로 표시하기 위해서:_를 사용할 수 있지만, 이것은 반드시 필요한 것이 아니다.:(Num:_ $)Num $는 같다.

구속 반환 유형

--> 표시 뒤에 있는 유형에 따라 하위 루틴이 실행될 때 유형 검사를 강제로 합니다.반환 유형 화살표는 매개변수 목록 뒤에 있어야 합니다.서명 성명 뒤에 있는 returns 키워드와 같은 기능이 있습니다.Nil는 유형 검사에서 정의된 것으로 여겨진다.
sub foo(--> Int) { 1 };
sub foo() returns Int { 1 };        #  
sub does-not-work(--> Int) { " " }; # throws X::TypeCheck::Return

형식 제약이 상수 표현식이라면, 하위 루틴의 반환값에 사용됩니다.그 서브루틴의 모든return 문장은 인자가 포함되지 않아야 합니다.
sub foo(--> 123) { return }
NilFailure는 항상 유형의 제약이 무엇이든지 되돌아오는 형식으로 허용된다.
sub foo(--> Int) { Nil };
say foo.perl; # Nil

유형 캡처 및 강제 유형은 지원되지 않습니다.

삼키기 매개변수(또는 길이 가변 매개변수)


수조나 산열 매개 변수는 앞의 별표 (s) 를 통해 삼키기 매개 변수로 표시할 수 있으며, 이것은 임의의 수량의 매개 변수 (0 개 또는 여러 개) 에 귀속될 수 있음을 의미한다.
그것들은 함수 중의 모든 잉여 파라미터를 삼키기 때문에 어떤 사람들이 국수를 삼키는 것처럼 삼키는 매개 변수라고 불린다.
:($a, @b)  #  ,   Positional  
:($a, *@b) #  , @b  
:(*%h)     #  ,  
sub one-arg (@)  { };
sub slury   (*@) { };

one-arg(5, 6, 7);  # !!!  
one-arg (5, 6, 7); # ok,   one-arg((5,6,7)) ,  

slurp (5, 6, 7);   # ok
one-arg 5, 6, 7;   #   one-arg(Int, Int, Int)  ,   (@),  
slurp 5, 6, 7;     # ok

one-arg (5);       # Calling one-arg(Int) will never work with declared signature (@)
one-arg (5,);      # ok

e-arg 함수에 필요한 매개 변수는 여러 개의 매개 변수가 아닌 목록(또는 수조)이다.
> (5).WHAT.say
(Int)
> (5,).WHAT.say
(List)
sub named-names (*%named-args) { %named-args.keys };
say named-names :foo(42) :bar  # => foo bar

위치 매개변수는 삼키기 매개변수 뒤에 나타날 수 없습니다.
:(*@args, $last) # !!!  

별표가 있는 삼키기 파라미터는 한 층 또는 여러 층의 누드를 녹여 교체 가능한 대상을 평평하게 한다.두 개의 별표가 있는 삼키기 매개변수는 매개변수를 벤드펴기하지 않습니다.
sub a (*@a)  { @a.join("|").say };
sub b (**@b) { @b.join("|").say };

a(1,[1,2],([3,4],5));    #  1|1|2|3|4|5
b(1,[1,2],([3,4],5));    # 1|1 2|3 4 5


일반적으로, 삼키는 매개 변수는 하나의 그룹을 만들고, 각argument에 벡터 용기를 만들고, 매개 변수의 값을 그 벡터에 부여합니다.만약 이 과정에서 매개 변수도 중간의 표량 분량이 있다면, 호출 함수에서 접근할 수 없습니다.
삼키기 파라미터는 특정traits and modifiers와 조합해서 사용할 때 특수한 행동을 합니다. 아래 설명한 바와 같이.

유형 캡처


형식 포획은 형식 제약에 대한 설명을 함수가 호출될 때까지 미루는 것을 허용합니다.그것들은 서명과 함수체의 유형을 모두 인용할 수 있도록 허용한다.
sub f(::T $p1, T $p2, ::C) {
    # $p1   $p2   T,  
    # C  
    my C $closure = $p1 / $p2;
    return sub (T $p1) {
        $closure * $p1;
    }
}

#   Int  ,  
#   &f  
my &s = f(10,2, Int.new / Int.new);
say s(2);  # 10 / 2 * 2  == 10

Positional vs. Named


매개 변수는 위치와 관련되거나 구명될 수 있다.모든 매개 변수는positional입니다. 삼키는 산열 매개 변수와 앞에 사칭 표시가 있는 매개 변수를 제외하고는:
:($a)   #  
:(:$a)  #   a  
:(*@a)  #  
:(*%h)  #  

호출자 쪽에서 위치 매개 변수의 전달 순서는 그것들의 성명 순서와 같다.
sub pos($x, $y) { "x = $x y = $y" };
pos(4, 5); #  x = 4 y = 5

구명실삼과 구명형삼의 경우 이름으로만 실삼을 형삼에 비추는 데 쓰인다.
sub named(:$x, :$y) { "x=$x y=$y" }
named( y => 5, x => 4);

구명 매개변수는 변수의 이름과 다를 수도 있습니다.
sub named(:official($private)) { " " if $private }
named :official;

별명도 그렇게 한다.
sub paint( :color(:colour($c)) ) { } # 'color'   'colour'  
sub paint( :color(:$colour) )    { } # same API for the caller

구명 매개 변수가 있는 함수는 동적으로 호출될 수 있으며, | 비연관적인Pair를 사용하여 구명 매개 변수로 변환할 수 있습니다.
multi f(:$named) { note &?ROUTINE.signature };
multi f(:$also-named) { note &?ROUTINE.signature };

for 'named', 'also-named' -> $n {
    f(|($n => rand))      # «(:$named)
(:$also-named)
»
}

my $pair = :named(1);
f |$pair; # «(:$named)
»

같은 구문을 사용하여 해시를 구명 매개변수로 변환할 수도 있습니다.
my %pairs = also-named => 4;
f |%pairs;        # (:$also-named)

옵션 및 필수 매개변수


Positional 매개 변수는 기본적으로 강제적이며 기본값 또는 끝 물음표를 사용하여 선택할 수 있습니다.
:(Str $id)         #   required parameter
:($base = 10)      #  ,   10
:(Int $x?)         #  ,   Int  

구명 매개변수는 기본적으로 선택적이며 매개변수 끝에 느낌표를 붙여 강제 매개변수로 만들 수 있습니다.
:(:%config)        #  
:(:$debug = False) #  ,   False
:(:$name!)         #   name  

기본값은 이전의 매개 변수에 의존할 수 있으며, 호출할 때마다 다시 계산됩니다.
:($goal, $accuracy = $goal / 100);
:(:$excludes = ['.', '..']); # a new Array for every call

해체 파라미터


매개 변수 뒤에는 괄호로 묶인 sub-signature 을 따라갈 수 있으며, 하위 서명은 주어진 매개 변수를 해설할 수 있다.분해 목록은 해당 요소입니다.
sub first (@array ($first, *@rest)) { $first }

또는
sub first ([$first, *@]) { $first }

산열의 해체는 키 값 쌍이다.
sub all-dimensions (% (:length(:$x), :width(:$y), :depth(:$z))) {
    sx andthen $y andthen $z andthen True
}
andthen 첫 번째 정의되지 않은 값을 되돌려줍니다. 그렇지 않으면 마지막 요소를 되돌려줍니다.단락 조작부호.andthen 왼쪽의 결과는 $_에 귀속되어 오른쪽에 사용되거나 매개 변수로 전달되며 오른쪽이 block 또는 pointy block일 경우.
일반적으로 대상은 그것의 속성 구조에 근거한다.일반적인 관용법은 for 순환에서 Pair 키와 값을 해제하는 것입니다.
for @guest-list.pairs -> (:key($index), :value($guest)) {
    ...
}

그러나 대상을 해제하는 것은 기본 행동일 뿐이다.대상이 서로 다른 방해구에 따라 그것들을 바꾸는 방법Capture

캡처 매개변수


매개 변수 앞에 수직|을 놓으면 매개 변수가 Capture로 변하고 나머지 위치 매개 변수와 구명 매개 변수를 모두 사용합니다.
이것은 proto 정의에서 (예를 들어 proto foo (|) {*}) 하위 루틴을 표시하는 multi 정의로 모든 종류의 제약을 가질 수 있다.

매개변수 특성 및 수정자


기본적으로 형식 매개 변수는 그들의 실참에 연결되어 읽기 전용으로 표시됩니다.traits 특성을 사용하여 매개 변수의 읽기 전용 특성을 변경할 수 있습니다.is copy 특성상 파라미터를 복사하고 하위 루틴 내부에서 파라미터의 값을 수정할 수 있습니다.
sub count-up ($x is copy) {
    $x = Inf if $x ~~ Whatever;
    .say for 1..$x;
}
is rw 특성상 파라미터는 변수에 귀속되거나 쓰기 가능한 용기에만 귀속됩니다.매개 변수에 값을 부여하면 호출된 변수의 값이 바뀝니다.
sub swap($x is rw, $y is rw) {
    ($x, $y) = ($y, $x);
}

삼키는 매개 변수에 대해 is rw 언어 디자이너가 보류하여 장래의 용도로 삼다

메서드


params 방법

method params(Signature:D:) returns Positional

서명을 구성하기 위해 대상 목록을 되돌려줍니다.

arity 방법

method arity(Signature:D:) returns Int:D

서명에 맞는 최소 수량의 위치 파라미터를 되돌려줍니다.

count 방법

method count(Signature:D:) returns Real:D

서명에 귀속될 수 있는 최대 수량의 위치 파라미터를 되돌려줍니다.삼키기 위치 파라미터가 있으면 되돌아오기Parameter.

returns 방법


서명이 반환되는 구속조건은 다음과 같습니다.
:($a, $b --> Int).returns # Int

ACCEPTS 메서드

multi method ACCEPTS(Signature:D: Capture $topic)
multi method ACCEPTS(Signature:D: @topic)
multi method ACCEPTS(Signature:D: %topic)
multi method ACCEPTS(Signature:D: Signature $topic)

세 가지 방법은 캡처에 연결될 수 있는지 여부를 볼 수 있습니다. 예를 들어 그 시그니처 함수를 가지고 있으면 Inf 호출할 수 있습니다.
(1,2, :foo) ~~ :($a, $b, :foo($bar)) # true
~~ :(Int $a)               # False

마지막으로 진실$topic이 받을 수 있는 모든 것을 $topic받을 수 있다.
:($a, $b) ~~ :($foo, $bar, $baz?)   # True
:(Int $n) ~~ :(Str)                 # False
Signature

좋은 웹페이지 즐겨찾기