티스토리 뷰

반응형

statements are not allowed at top level




아무짓도 안했는데.. 분명히 어제까지만 해도 잘 돌아가는 코드였는데 갑자기



statements are not allowed at top level라는 에러가 생겼습니다. 

전혀 문제가 없는 것 같은데..진짜 어제까지만 해도 잘 돌아가는 코드였거든요???

근데...왜..이런 현상이 발생했는지 알아보려고 합니다..ㅎㅎ 저같은 분들이 있을까봐 XD




왜 에러가 발생했다고 생각하시나요?

ㅎㅎ바로..swift파일의 '이름'에 있습니다. 























저는 앞으로 이 프로젝트에서 백준 문제를 풀려고 하는데, 

swift파일 이름들을 '문제 번호'로 하고싶었어요...그뿐이에요..

그런데 이 swift파일이름이 원래 뭔지 아시나요?

네. 프로젝트를 새로 생성하면 



네. main.swift라고 되어있을거에요.

이게 무슨상관이냐구요?




음..매우 상관있어요. 

일단, 저 statements are not allowed at top level 이라는 소리.

무슨말일까요? 

최상위 레벨에서의 서술?(코드를 의미하는 것 같아요)은 허용되지 않습니다.

라는 소리같네요.


자. 이 최상위 레벨이 무엇인지 부터 알아볼게요. 

근데 저.. 오류... 어디선가 본 적 있지 않으신가요?


네. 바로 iOS앱을 만드는 프로젝트에서 생겼던 오류네요.
하지만,


또한, 저 ViewController라는 클래스가 없어도



이렇게만 해도 오류가 없어지게 됩니다.

그냥 함수로 묶어준 것 뿐인데, 왜 그냥 함수 없이 쓰면 최상위레벨오류(statements are not allowed at top level에러를 말하는 것입니다XD)가 생길까요?


그것은 바로 애플이 그렇게 지정해서....ㅎ입니다.


Swift 응용 프로그램은 함수, 클래스 응용 프로그램을 구성하는 다른 선언을 포함한 여러 개의 파일로 구성되어 있어요.

응용 프로그램의 대부분의 Swift 파일은 순서에 의존하지 않아요.(order-independent)

, 정의되기 전에 타입을 사용할 있으며 파일의 마지막에 있는 모듈을 가져올 있습니다.

그러나 대부분의 Swift 소스 파일에서 최상위 코드는 허용되지 않습니다. 

명확하게하기 위해 함수 본문에서 클래스 또는 기타의 방법으로 캡슐화되지 않은 명령문은 최상위로 간주됩니다. 

모든 파일에서 최상위 코드가 허용되어 있으면 프로그램의 시작 위치를 결정하는 것이 어렵기 때문에이 규칙이 있습니다.



ㅡㅡ아니 그럼 playground(플레이 그라운드)에서는 왜 오류 안떠요????

엄청엄청 잘되고 결과도 바로바로 보여주는데;


일단 예제를 하나 볼까요? 플레이 그라운드에서는 입력을 받을 수 없다는 것은 이제 다 아시죠?

그럼 위에 했던 예제는 안되겠고 간단하게 Hello World를 출력하는 문을 생각해봅시다. 


print("Hello World")

자, 이것은 캡슐화가 되어있지 않기 때문에 최상위오류 에러를 내야하죠.

하지만 플레이그라운드에서는 아주 잘 작동하는 것을 볼 수 있습니다.


그럼 플레이그라운드랑 Swift파일에서 실행하는 거랑 뭐가 다른거지??할 수 있어요. 

간단하게 생각하시면 됩니다.

플레이그라운드는 최상위코드의 실행을 지원하고있기 때문에 위 예제는 아주 문제없이 잘 돌아갑니다. 또한, 플레이그라운드는 순서에 의존적이에요.(order-dependent) 순서에 따라 코드가 달라지죠? 하향식으로요.




그래그래.. 알겠어요....Single View application(iOS앱 만들 때 쓰는 프로젝트)에서 캡슐화를 안시키면 에러가 나고, 플레이그라운드에서는 최상위 코드의 실행을 지원하니까 실행이 된다는 거 알겠어요..

근데 왜!!! command line Tool에서 만든 swift파일에서 오류가 나는 이유가 뭔데.....ㅎ




네..뭐 눈치채신 분들도 있을지도 모르지만 바로 "이름"에 있습니다.

방금전에 대부분의 앱의 소스파일에 최상위코드를 사용할 수 없다고 말씀드렸죠? 

하지만 예외가 있습니다. 

바로 "main.swift"라는 특별한 파일이죠.

이것은 플레이그라운드의 파일과 비슷하지만 응용프로그램의 소스코드로 구축되어 있어요.

 "main.swift"파일에는 최상위코드를 포함할 수 있으며, 플레이그라운드와 마찬가지로 순서에 의존적입니다. 

실제로  "main.swift"에서 실행되는 첫번째 코드줄은 프로그램의 기본 진입점(entry point)으로 암시적으로 정의됩니다. 



그렇다면 왜 iOS프로젝트에서는 main.swift가 없는 것일까요?

그 이유는 Xcode에서 Mac 템플릿은 기본적으로 "main.swift"파일을 포함하지만 iOS 응용 프로그램의 경우 새로운 iOS 프로젝트 템플릿의 기본값은 @UIApplicationMain을 일반 Swift 파일에 추가하는 것입니다. 이로 인해 컴파일러가 iOS 앱의 기본 진입 점을 합성하고 "main.swift"파일의 필요성을 없애줍니다.





여기 애플이 작성한 문서에 가보시면 더 많은 정보를 알 수 있어요. 저는 여기서 핵심만 가져온거구요.

아니 의아한게 이 오류를 처음에 구글에 쳤을 때, 많은 사람들이 캡슐화 하는 방식으로 문제를 해결하더라구요..


근데 애플이 계속  "main.swift"거리길래.. 혹시..이름때문인가 해서 이름을 1000.swift에서 main.swift로 바꾸어봤더니 아주 잘 실행되었어요 ^^..

왜 아무도 이 방법을 안알려주는거지..ㅎㅎ..스택오버플로우에 이러한 오류를 겪고 있으신 분들이 굉장히 많은 것 같았는데 다들 이름을 바꿔봐!!라고 아무도...가르쳐주지 않았어요..


결론 : 코딩을 하는데, statements are not allowed at top level 오류가 난다. -> 현재 swift파일 이름이 main.swift인지 확인한다. -> 아니라면 main.swift로 바꿔준다. 


그리고 혹시.. 비쥬얼 처럼 프로젝트에서 제외시키고 파일 여러개 만들어서 코딩하는 법 아시는 분 있다면 댓글로 알려주세요...원래 이름 예쁘게 해서 문제마다 파일 만들어서 git에 올릴려고 하다가...이까지 와버렸네요 ^^!!...main.swift는 프로젝트 당 하나만 가질 수 있는데.. 문제마다 프로젝트를 만들어야 하는건지 ^^^!!!!!!!!


아무튼 도움이 되었으면 좋겠어요!!XD

반응형