중첩 함수란 무엇입니까?그것들은 무엇을 위한 것인가요?
-
22-08-2019 - |
문제
나는 중첩 함수를 사용한 적이 없지만 여러 언어에서 해당 함수에 대한 참조를 본 적이 있습니다(관련이 있다고 가정하는 중첩 클래스도 포함).
- 중첩 함수란 무엇입니까?
- 왜?!?
- 다른 방법으로는 할 수 없는 중첩 함수로 무엇을 할 수 있나요?
- 중첩 함수 없이는 어렵거나 우아하지 않은 중첩 함수로 무엇을 할 수 있나요?
나는 중첩된 함수가 모든 것을 객체로 취급하는 단순한 인공물이라고 가정하고, 객체가 다른 객체를 포함할 수 있다면 그 함수는 따릅니다.
함수 내부의 변수에 범위가 있는 것처럼 중첩된 함수에도 범위가 있습니까(일반적으로 언어에 따라 다르다고 가정합니다)?
귀하의 답변이 언어에 구애받지 않는지 확실하지 않은 경우 참조하는 언어를 추가하십시오.
-아담
해결책
중첩 된 기능의 대중적인 사용은 중 하나입니다 폐쇄. 안에 어휘 스코핑 일류 기능이있는 언어 기능을 사용하여 데이터를 저장할 수 있습니다. 체계의 간단한 예는 카운터입니다.
(define (make-counter)
(let ((count 0)) ; used to store the count
(define (counter) ; this is the counter we're creating
(set! count (+ count 1)) ; increment the count
count) ; return the new count
counter)) ; return the new counter function
(define mycounter (make-counter)) ; create a counter called mycounter
(mycounter) ; returns 1
(mycounter) ; returns 2
이 예에서는 함수 메이크 카운터 내부의 기능 카운터를 중첩 하고이 내부 기능을 반환하면 정의 할 때 카운터 할 수있는 데이터에 액세스 할 수 있습니다. 이 정보는 MyCounter 의이 인스턴스에 비공개입니다. 다른 카운터를 만들려면 다른 지점을 사용하여 내부 수를 저장합니다. 이전 예에서 계속 :
(define mycounter2 (make-counter))
(mycounter2) ; returns 1
(mycounter) ; returns 3
다른 팁
그것을 호출 할 방법이 1 개 밖에 없을 때 재귀에 유용합니다.
string[] GetFiles(string path)
{
void NestedGetFiles(string path, List<string> result)
{
result.AddRange( files in the current path);
foreach(string subPath in FoldersInTheCurrentPath)
NestedGetFiles(subPath, result);
}
List<string> result = new List<string>();
NestedGetFiles(path, result);
return result.ToArray();
}
위의 코드는 완전히 구성되지만 C#을 기반으로하는 것이 무엇을 의미하는지에 대한 아이디어를 제공합니다. NestEdgetFiles를 호출 할 수있는 유일한 방법은 getfiles 메소드입니다.
중첩 된 함수는 다른 함수 내부의 함수 일뿐입니다.
예, 모든 것이 대상이 된 결과입니다. 함수의 범위에만 표시되는 변수를 가질 수 있고 변수는 함수를 가리킬 수 있으므로 로컬 변수에 의해 참조되는 함수를 가질 수 있습니다.
나는 당신이 절대적으로 할 수없는 중첩 된 기능으로 할 수있는 일이 없다고 생각합니다. 그러나 많은 시간이 의미가 있습니다. 즉, 함수가 다른 기능의 "하위 기능"일 때마다.
나에게 일반적인 사용 사례는 함수가 복잡한 논리를 많이 수행 할 때이지만, 함수가 계산/반환하는 내용은 논리에 의해 지시 된 모든 경우에 대해 쉽게 추상화 할 수 있습니다.
(C#) : 객체 브라우저보기를 단순화하고 클래스를 더 잘 구성하는 데 사용합니다. 트럭 클래스에 중첩 된 클래스 휠로.
이 세부 사항을 잊지 마십시오. "중첩 된 유형은 상속 된 개인 또는 보호 된 구성원을 포함하여 포함 된 유형의 개인 및 보호 회원에 액세스 할 수 있습니다."
중첩된 함수를 사용하면 해당 함수 내에서 한 함수의 내부 작동에만 관련된 코드를 캡슐화하는 동시에 가독성이나 일반화를 위해 해당 코드를 분리할 수 있습니다.일부 구현에서는 외부 범위에 대한 액세스도 허용합니다.D에서:
int doStuff() {
int result;
void cleanUpReturn() {
myResource1.release();
myResource2.release();
return result * 2 + 1;
}
auto myResource1 = getSomeResource();
auto myResource2 = getSomeOtherResource();
if(someCondition) {
return cleanUpReturn();
} else {
doSomeOtherStuff();
return cleanUpReturn();
}
}
물론 이 경우 RAII로도 처리할 수 있지만 이는 단순한 예일 뿐입니다.
기능을 다른 기능으로 인수로 전달 해야하는 경우에도 유용 할 수 있습니다. 또한 공장 기능 (파이썬)의 공장 기능을 만드는 데 유용 할 수 있습니다.
>>> def GetIntMaker(x):
... def GetInt():
... return x
... return GetInt
...
>>> GetInt = GetIntMaker(1)
>>> GetInt()
1
중첩 된 함수는 단순히 다른 함수의 본문 내에서 정의 된 함수입니다. 왜요? 내가 머리 꼭대기에서 생각할 수있는 유일한 이유는 도우미 또는 유틸리티 기능입니다.
이것은 고안된 예이지만 나와 함께 견뎌냅니다. 결과에 두 개의 쿼리를 수행하고 쿼리 중 하나의 값으로 객체를 채워야하는 함수가 있다고 가정 해 봅시다. 당신은 다음과 같은 일을 할 수 있습니다.
function process(qryResult q1, qryResult q2) {
object o;
if (q1.someprop == "useme") {
o.prop1 = q1.prop1;
o.prop2 = q1.prop2;
o.prop3 = q1.prop3;
} else if (q2.someprop == "useme") {
o.prop1 = q2.prop1;
o.prop2 = q2.prop2;
o.prop3 = q2.prop3;
}
return o;
}
20 개의 속성이있는 경우 코드를 복제하여 객체를 계속해서 설정하여 큰 기능으로 이어집니다. 간단한 중첩 기능을 추가하여 쿼리에서 객체로의 속성 사본을 수행 할 수 있습니다. 이와 같이:
function process(qryResult q1, qryResult q2) {
object o;
if (q1.someprop == "useme") {
fillObject(o,q1);
} else if (q2.someprop == "useme") {
fillObject(o,q2);
}
return o;
function fillObject(object o, qryResult q) {
o.prop1 = q.prop1;
o.prop2 = q.prop2;
o.prop3 = q.prop3;
}
}
물건을 조금 더 깨끗하게 유지합니다. 중첩 된 기능이어야합니까? 아니요,하지만 프로세스 함수 가이 사본을 수행 해야하는 유일한 프로세스 기능이라면 이런 식으로 수행 할 수 있습니다.