PHP에서 Golang으로의 참고사항(전송)
———기사 출처 YamiOdymel/PHP-to-Golang
PHP와 모듈의 관계가 귀찮습니다. yaml 파일을 읽으려면 yaml 모듈이 필요합니다. , 이를 위해서는 여전히 컴파일한 후 지정된 위치에 컴파일된 모듈을 배치해야 합니다. 그 후에는 서버를 변경할 때 다시 컴파일해야 합니다. 그런데 이 점은 출시 이후에도 아직 개선되지 않았습니다. PHP 7에서는 성능이 실제로 많이 향상되었지만(Python 3보다 빠릅니다), PHP는 여전히 부풀어오르는 느낌을 줍니다
(직업 전환).
PHP와 Golang의 성능이 더 빠르다는 것은 의심의 여지가 없다고 생각합니다(그리고 이는 배수로 계산됩니다). 어떤 사람들은 둘을 함께 비교하면 안 된다고 생각할 수도 있지만 저는 Golang 자체가 더 좋습니다. 웹 개발을 하기 때문에 Golang으로 전환을 고려하게 되었습니다. 처음에는 Node.js와 Rust, 그리고 최종적으로 선택한 Golang을 먼저 살펴보겠습니다.
Node.js의 성능은 PHP보다 3.5배~6배 정도 빠르다고 할 수 있고, 작성 언어는 JavaScript이므로 새로운 언어를 배울 필요가 없습니다! Babel과 짝을 이루면 만능이라고 할 수 있지만 "Tigger"와 동일한 Async 로직과 무서운 Callback Hell을 사용하면 전자가 장점이라고 생각하는 사람들도 있지만 부정하지는 않습니다. PHP를 배우는 저에게는 너무 "Mind Fuck"입니다. 후자의 Callback Hell은 Promise가 있지만 또 다른 "Then Hell" 이야기입니다. Golang과 비교할 때 Node.js는 나에게 그다지 매력적이지 않은 것 같습니다. 실제로 Node.js로 많은 것을 작성할 수 있지만 V8 엔진의 성능은 여전히 제한적이며 새로운 것을 배우려면 "새로워야" 해야 하지 않나요 ;)?
주제 외: Node.js가 대규모 상업 프로젝트에 적합하지 않은 이유는 무엇입니까?
Node.js를 버리고 Node.js로 전환한 후 하루 동안 Rust와 Iron 프레임워크를 사용해 보았습니다. 흠? Rust는 너무 강력해서 여기서는 Rust를 사용하면 안 된다고 생각합니다. 어쩌면 이 아이디어는 어리석은 것일 수도 있지만 Rust를 사용하면 네트워크 서비스보다는 시스템이나 일부 낮은 수준의 장소에서 사용해야 한다는 느낌을 받게 됩니다.
Golang은 나의 최종 선택입니다. 주로 하루 동안 조사했을 때 우연히 Golang이 매우 단순하고(단지 25개의 키워드) 그에 비해 Rust가 너무 "강력"하다는 사실을 발견했기 때문입니다. Golang에는 자동으로 코드를 구성하는 데 도움이 되는 go fmt, 자동으로 파일 생성에 도움이 되는 go doc, 자동으로 단위 테스트를 수행하고 적용 범위 보고서를 생성할 수 있는 go test, 패키지 관리 기능이 포함되어 있습니다. 도구(버전 기능은 없지만)는 매우 실용적이며 세미콜론( ; )을 추가할 필요가 없습니다. 이 도구의 정말 나쁜 점은 아마도 새 줄에 넣지 않고 중괄호를 넣어야 한다는 것입니다(예). , 나는 꽃이다 괄호는 새로운 줄로 묶일 것입니다).
이 문서를 작성할 때, 여러분은 어떤 기초를 가지고 있다고 가정하겠습니다. 먼저 다음 매뉴얼을 읽으시면 됩니다.
PHP에서 변수를 만들고 싶을 때 직접 만들면 되겠죠?
조개찜! 골랭은 어떻습니까? Golang의 변수는 "새 정의", "사전 정의", "자동 새 정의" 및 "재정의" 등 여러 범주로 나뉩니다. 예를 살펴보겠습니다.
PHP에서는 다음과 같이 텍스트를 표시하기 위해 에코를 자주 사용합니다.
그러나 Golang에서는 fmt 패키지가 필요합니다. 기사 아래에서 "패키지란 무엇인가"에 대해 알아볼 수 있습니다.
이것은 매우 간단하며 두 언어의 사용법은 매우 다릅니다. PHP는 다음과 같습니다.
다만 Golang이 조금 더 시끄럽다는 점만 선언해야 합니다. 함수 뒤에 어떤 데이터 유형이 반환되는지.
PHP에서는 여러 개의 데이터를 반환하고 싶다면 배열을 사용한 후, 다음과 같이 배열에 데이터를 넣게 됩니다.
그러나 Golang에서는 배열을 사용할 필요가 없으며 함수는 한 번에 여러 값을 반환할 수 있습니다.
두 언어는 서로 다른 언어로 작성되었습니다. 방법.
주로 PHP 배열은 너무 많은 일을 할 수 있기 때문에 PHP에서 원하는 것을 저장하려면 배열을 사용하세요.
Golang에는 그런 전능한 것이 없습니다. 먼저 Golang의 이러한 유형을 이해해야 합니다: 배열, 슬라이스, 맵, 인터페이스,
도대체 내가 보는 것은 무엇입니까? 세 가지 이유 때문에 먼저 Golang은 강력한 유형의 언어라는 점을 알아야 합니다. 이는 배열이 한 가지 유형만 가질 수 있다는 것을 의미합니다. 이 배열을 문자열 데이터 배치에 사용하기로 결정한 경우 해당 배열에는 문자열만 넣을 수 있습니다. 여자친구가 없는 것처럼 숫자 값도 볼린저 값도 없습니다.
PHP의 "범용 배열"은 제쳐두세요. Golang의 배열은 간단하지만 매우 어리석습니다. 배열을 정의할 때 해당 내용을 저장할 길이와 데이터 유형을 지정해야 합니다. 길이를 채울 필요는 없지만 배열 내용은 원래 정의한 길이를 초과할 수 없습니다.
슬라이싱? 이상하게 들릴 수도 있지만 실제로 "슬라이스"가 "배열"보다 나은 점에 대해 이야기해 보겠습니다. "최대 길이를 정의할 필요가 없습니다. 그리고 더 이상 값을 직접 할당할 수 없습니다.
방금 그를 "자르기"할 수 있다고 언급했는데, 기억하시나요? 이는 PHP의 array_slice()와 약간 비슷하지만 Golang에서는 Slice를 이 사용법을 직접 "내장"하고 사용법은 다음과 같습니다.
PHP에서는 그다지 편리하지 않습니다. 다음 PHP 예제에서는 array_slice()를 지속적으로 사용해야 합니다.
"매핑"을 키 이름과 키 값이 있는 배열로 생각할 수 있지만 "키 이름과 키 값의 데이터 유형을 미리 정의해야 합니다"라는 점을 기억하세요. 제한이 있습니다. 이미지에 여러 가지 유형의 데이터를 저장할 수 있는 방법은 없습니다.
Golang에서는 먼저 make()를 사용하여 맵을 선언해야 합니다.
'인터페이스'라는 단어가 마음에 들지 않으실 수도 있겠지만, '인터페이스'를 사용하면 대중이 오해를 살 수 있을 것 같아 계속해서 '인터페이스'라고 부르겠습니다. 이와 같이 PHP의 연관 배열에 모든 유형의 데이터를 저장할 수 있다는 것을 기억하십니까?
이제 당신은 축복받았습니다! Golang의 인터페이스{}는 모든 콘텐츠를 수용할 수 있기 때문에 이를 사용하여 모든 유형의 데이터를 저장할 수 있습니다.
때로는 마음이 바뀌는 여자친구처럼 PHP에서는 변수를 직접 문자열, 숫자 또는 null 값으로 정의할 수 있습니다. . 변화.
Golang에서는 변수에 특정 데이터 유형을 지정해야 합니다. 하지만 제가 방금 언급한 내용을 기억하세요. "Golang에는 무엇이든 저장할 수 있는 인터페이스가{} 있습니다."(실제로는 아무것도 아니지만요. 뭐?) ?
프로그램에서 더 이상 리소스를 사용할 필요가 없거나 오류가 발생하는 경우 PHP에서 파일을 읽는 것과 같은 리소스 오버헤드를 절약하기 위해 리소스를 닫거나 버리면 됩니다.
p>Golang에서는 defer를 사용하여 함수 종료 시 특정 프로그램(실행 방향이 반대)을 자동으로 실행할 수 있습니다. 따라서 함수가 끝날 때 전면 리소스를 종료할 필요가 없습니다.
defer는 "지연된 실행"이라고 할 수 있는데, 이는 실제로 함수가 끝난 후 "역순"으로 실행되는 것입니다. 예를 들어, 다음 순서로 defer를 정의합니다. A-gt; gt;C-gt;D인 경우 실제로 실행 순서는 D-gt;C-gt;B-gt;A가 됩니다. 이는 프로그램 마지막에 매우 유용합니다. Golang이 위의 예를 어떻게 개선할 수 있는지 살펴보겠습니다. .
이거 정말 사악한 것 아닌가요? 나는 BASIC을 작성하고 있지는 않지만 때로는 PHP에서 BASIC을 사용하게 될 것입니다. 하지만 그러지 마세요.
Golang에는 for 루프만 있지만 foreach, while 및 for를 여러 번 사용할 수 있습니다. 일반적인 for 루프가 작성되는 방식은 두 언어 모두에서 매우 유사합니다.
Golang에서는 기억하세요: i가 이전에 존재하지 않았다면 이를 정의해야 하므로 다음 예에서는 i := 0 을 볼 수 있습니다.
PHP에서 foreach()는 사용하기 매우 간단한 값과 키 이름을 직접 제공할 수 있습니다.
Golang에는 for()만 있지만 range를 사용하면 PHP와 동일한 foreach 메서드를 구현할 수 있습니다.
PHP의 while(조건) 루프는 조건이 거짓이 될 때까지 블록의 프로그램을 계속 실행할 수 있습니다.
Golang에서도 동일한 접근 방식이 수행되지만 여전히 for 루프를 통과합니다. 이 for 루프에는 세미콜론( ; )이 없으며 무조건 for 루프가 항상 실행됩니다.
PHP에는 블록에서 먼저 작업을 수행할 수 있는 do .. while() 루프가 있습니다.
Golang에는 관련 함수가 없지만 무한 for 루프에 조건식을 추가하여 루프를 종료할 수 있습니다.
정말로 PHP와 같은 디자인 방법을 완전히 따르고 싶다면 Golang에서 매우 사악한 goto를 사용할 수 있습니다.
PHP에서는 다음과 같이 date()를 통해 현재 날짜를 얻을 수 있습니다.
Golang에서는 조금 더 흥미롭습니다. 왜냐하면 Golang은 Y-m-d 형식이 아니라 1, 2, 3 형식으로 정의되어 있기 때문입니다. 이를 위해서는 1의 의미를 알기 위해 파일을 읽어야 합니다. 을 위한.
속담처럼: "폭발은 예술이다." 폭발()(폭발), die()(죽음)과 같은 사랑스러운 PHP 단어는 정말 대담합니다. PHP에서 문자열을 배열로 분할하려면 이렇게 하면 됩니다.
단순히 문자열을 "폭발"시키자면 Golang은 어떻습니까?
그런데 strings 패키지를 인용하는 것을 잊지 마세요.
이것은 실제로 매우 일반적으로 사용되는 함수입니다. 객체와 마찬가지로 키 이름과 키 값이 있습니다. PHP에서는 배열(Array)을 사용하여 쉽게 수행할 수 있습니다.
좋은데 Golang은 어떻습니까? 지도 사용은 거의 동일합니다. 필요한 경우 앞서 언급한 "다중 데이터 저장소 유형-저장소"를 검토할 수 있습니다.
PHP에서는 인덱스가 있는지 확인하기 위해 isset()을 자주 사용하시죠?
이는 Golang에서 수행하기 매우 쉽습니다( map 에만 적용 가능).
포인터(때로는 참조이기도 함)는 "변수 앨리어싱"과 같은 방법입니다. 이 방법을 사용하면 하루 종일 이전 변수를 덮어쓰지 않아도 됩니다. 이때 A = 1; , B는 A의 복사본을 만들고 두 개는 서로 관련이 없습니다. B를 수정할 때 실제로 A의 값을 수정하려면 포인터가 필요합니다.
포인터는 변수를 복사하는 대신 변수를 가리키는 메모리 위치를 생성하므로 포인터를 변경하면 실제로 변수가 변경됩니다.
Golang에서는 * 및 amp; 기호를 사용해야 합니다.
때로는 데이터와 오류 코드가 포함될 수 있는 배열을 반환하고 조건문을 사용하여 오류 코드가 null이 아닌지 확인합니다.
Golang에서는 함수가 한 번에 여러 값을 반환할 수 있습니다. 이렇게 하려면 실제로 배열을 반환할 필요는 없지만 오류 데이터 유형의 오류를 반환하게 되므로 이를 수행하는 데 도움이 되도록 오류 패키지를 참조해야 합니다.
Golang에서는 try .. catch가 없다는 점에 유의해야 합니다. Golang에서는 이 오류 처리 방법을 권장하기 때문에 나중에 try를 아무데나 사용하는 것보다 오류가 발생할 수 있는 프로그램을 실행할 때마다 오류를 처리해야 합니다. . 프로그램을 래핑하세요.
if 조건부에서 변수를 선언하면 전역 범위를 오염시키지 않고 if 내부에서만 변수를 사용할 수 있습니다.
아마도 PHP에서 더 일반적으로 사용하는 것은 try .. catch일 것입니다. 대규모 비즈니스 로직에서 이러한 사용법을 자주 볼 수 있습니다. 실제로 이 사용법은 많은 try 블록이 필요하기 때문입니다. ):
Golang에는 try .. catch가 없습니다. 실제로 Golang에서는 이러한 동작을 권장하지 않습니다(Golang에서는 오류를 하나씩 처리하도록 권장합니다). 예외가 발생하면 실제로 Golang에서 오류를 처리하는 다른 방법을 사용할 수 있습니다(가능하면 이 방법을 사용하지 마십시오): 당황(), 복구(), 연기.
Panic()을 던지기(오류 던지기)로 생각할 수 있는데, 이는 PHP의 Exit()와 유사합니다. 일단 Panic()을 실행하면 프로그램이 end를 선언하지만 걱정하지 마세요. 프로그램이 종료되면 defer가 호출되므로 다음 defer에서nic()을 중지해야 합니다.
defer에 대해서는 위에서 언급한 바 있으며, 함수가 종료된 후에 실행됩니다. 프로그램을 종료하기 위해 defer도 실행됩니다. 따라서 프로그램이 종료 작업을 계속하는 것을 중지하려면 defer 내에서 Recover()를 사용해야 합니다. 이는 예외를 잡는 것과 같습니다.
복구()는 catch로 간주될 수 있습니다. 프로그램이 종료되지 않고 정상으로 돌아가도록 하려면 다시 패닉()을 해결하기 위해 연기하는 데 복구()를 사용해야 합니다.
PHP에서 여러 파일을 참조해야 했던 시절을 기억하시나요? require() 또는 include()가 어디서나 보입니까? Golang에서는 이러한 기능이 사라지고 "Package"로 대체되었습니다. 이제 PHP로 설명해보자.
이게 정상인 것 같죠? 하지만 파일이 많다고 가정하면 이는 즉시 Include Hell이 됩니다. Golang이 "키트"를 통해 이 문제를 어떻게 해결하는지 살펴보겠습니다.
"어? 샤오샤오를 죽이라고?" 예, main.go는 fmt 패키지(결과를 출력하는 데 사용되는 패키지)를 제외하고 a.go를 전혀 참조하지 않습니다.
"어? 샤샤오" 몇 초 전의 자신으로 돌아간 것 같아요.
다른 파일은 참조되지 않는데 왜 main.go에서 foo를 출력할 수 있나요? 둘 다 메인 패키지에 속해 동일한 영역을 공유하므로 다음으로 소개해드릴 것은 "스위트"라는 것입니다.
패키지는 다음과 같이 모든 .go 파일이 Golang 소스 코드에서 선언해야 하는 첫 번째 항목입니다.
이는 현재 파일이 기본 패키지에 속한다는 것을 의미합니다(사용자는 원하는 대로 이름을 지정할 수도 있습니다. 그렇다면 동일한 패키지에 있는 함수 간에 어떻게 통신합니까?
다음은 Golang입니다. 다음 두 파일은 동일한 패키지에 속하므로 어떤 파일도 참조할 필요가 없습니다.
"키트"로 제어되는 세상은 PHP의 include() 및 require()보다 훨씬 낫습니다. 그렇죠?
Golang에서는 별도의 파일을 참조할 수 있는 방법이 없습니다. 전체 패키지를 가져와야 하며, 아래와 같이 "가져올 경우 반드시 사용해야 합니다"라는 점을 기억해야 합니다.
가져온 패키지를 사용하지 않고 해당 패키지의 main() 기능을 트리거하기 위해 참조만 하는 경우 앞에 밑줄(_)을 추가할 수 있습니다.
패키지에 이름 충돌이 있는 경우 패키지 소스 앞에 새 이름을 지정할 수 있습니다.
이제 패키지를 가져올 수 있다는 것을 알았으니 "내보내기"가 무엇인가요? 동일한 패키지에 있는 함수와 공유 변수는 실제로 직접 사용할 수 있지만 이것이 다른 패키지에서 사용할 수 있다는 의미는 아닙니다. 이 방법은 함수/변수의 "초기 사례"에 따라 다릅니다.
그렇습니다. Golang은 함수/변수의 초기 사례를 기반으로 이 항목을 "내보낼" 수 있는지 여부를 결정합니다.
이는 함수를 구별할 때 특히 유용합니다. 소문자로 시작하는 것은 내보내기용이 아니며, 반대로 대문자로 시작하는 것은 내보내기용이고 다른 패키지에서 사용되기 때문입니다.
처음에는 이것이 이상한 규칙이라고 생각할 수도 있지만 오랫동안 작성해 보면 JavaScript 및 Python의 "결론부터 시작하는 명명 방법"보다 낫다는 것을 알게 될 것입니다. 비공개적이고 항상 보호되는 속도가 더 빨라질 것입니다.
Golang에는 카테고리가 없지만 거의 모든 요구 사항을 충족할 수 있는 소위 "구조체"와 "인터페이스"가 있습니다. 이것이 바로 Golang이 매우 간단하다고 생각하는 이유입니다. .
먼저 PHP에서 카테고리를 만든 다음 Golang이 이 문제를 어떻게 해결하는지 살펴보겠습니다.
Golang에는 카테고리가 없지만 "Struct"는 매우 유용합니다. 우선 Golang의 "카테고리" 멤버와 메소드가 "카테고리" 외부에 있다는 점을 알아야 합니다. PHP가 카테고리 내에서 정의하는 방식과 다릅니다. Golang의 또 다른 점은 공개, 비공개 또는 보호 유형이 없다는 것입니다.
PHP에서는 카테고리가 새로 생성되면 해당 카테고리의 생성자(__construct())가 자동으로 실행됩니다. 일반적으로 이를 사용하여 카테고리의 일부 내부 값을 초기화합니다.
하지만 Golang에는 카테고리가 없기 때문에 생성자가 없습니다. 아쉽게도 생성자 자체에는 생성자의 특성이 없습니다. 이때는 외부 생성자를 직접 생성할 수만 있습니다. .
두 개의 카테고리가 있고 한 카테고리를 다른 카테고리에 전달하여 사용한다고 가정해 보겠습니다. 더 이상 말도 안 되는 일이 아닙니다! PHP 예제부터 시작하겠습니다(간결함을 위해 줄 바꿈을 생략했습니다).
Golang에서도 동일한 사용법이 있지만 "모든 것은 "범주" 외부에서 구성됩니다."라는 점을 기억하십시오.
PHP에는 관련 예제가 없습니다. 이 부분에서는 지금 설명 개체로 "Embedding" 장의 Golang 예제를 사용합니다.
Golang이 Foo를 Bar에 포함시키면 Bar 아래에 Foo의 멤버가 자동으로 노출된다는 것을 알 수 있습니다. 그렇다면 "양 당사자가 동일한 멤버 이름을 가지고 있다면" 어떻게 될까요?
이때 내장된 멤버는 "섀도잉"됩니다. 다음은 섀도잉 문제를 해결하는 실제 예입니다.
모두 동일한 함수를 호출하지만 이는 함수는 다양한 데이터 소스에 대해 다양한 작업을 수행할 수 있는데, 이것이 바로 다형성입니다. 이것을 다음과 같이 생각할 수도 있습니다. "메시지의 의미는 보내는 사람이 아니라 받는 사람에 의해 정의됩니다."
현재 PHP에는 진정한 "다형성"이 없지만 여전히 동일한 것을 만들 수 있습니다.
응, Golang은 어때? 실제로는 더 간단하고 체계적이며, Golang에는 이를 도와줄 수 있는 인터페이스가 있습니다.
인터페이스에 익숙하지 않다면 "Golang에서 인터페이스가 무엇인지 설명하기" 기사를 확인해 보세요.
이 글을 읽어주셔서 감사합니다. 불행하게도 이 글에는 Golang의 가장 중요한 판매 포인트인 "고루틴"과 "채널"이 언급되어 있지 않습니다.