>  기사  >  백엔드 개발  >  PHP를 go 또는 java로 변환하시겠습니까?

PHP를 go 또는 java로 변환하시겠습니까?

王林
王林원래의
2019-09-07 16:00:547037검색

PHP를 go 또는 java로 변환하시겠습니까?

일부 PHP 사용자는 Go 또는 Java로 전환하는 것을 고려할 것입니다. 이 두 언어를 간단히 비교해 보겠습니다. 이 글은 참고용입니다!

Go 언어

Go 언어는 Java와 비교하여 기계어 코드로 컴파일된 후 직접 실행됩니다. C언어와 많이 비슷합니다. 가상 머신이 없기 때문에 Java와는 매우 다릅니다. 이는 객체 지향적이며 어느 정도 자동 가비지 수집 기능을 갖춘 새로운 C 언어가 아닙니다. Java 프로그래머의 관점에서 볼 때 Go 언어를 배우는 것은 매우 어려운 일이며 객체, 클래스 및 기타 모든 언어 구성 요소와 함께 프로그래밍 언어 구성에 대한 더 깊은 이해에 도움이 될 수 있는 것들이 있습니다. 심지어 Java에서도 언어 구성 요소에 무슨 일이 일어나고 있나요? .

Go 언어의 객체 지향 구현을 이해한다면 이러한 것들을 Java 언어로 구현하는 다양한 방법도 이해하게 될 것입니다.

가비지 컬렉션 사용 여부

프로그래밍 언어에서는 메모리 관리 부분이 매우 중요합니다. 어셈블리 언어는 모든 것을 할 수 있게 해준다. 아니 오히려 모든 것을 하라고 요구한다. C 표준 라이브러리는 메모리 관리를 위한 몇 가지 기본 기능을 제공하지만, 여전히 메모리 할당을 위해 malloc을 호출한 후 수동으로 해제해야 합니다. 자동화된 메모리 관리 기술은 C++, Python, Swift 및 Java와 함께 등장했습니다. Go 언어도 그 중 하나입니다.

Java 및 기타 JVM 언어(Python의 JVM 구현 포함)의 경우 메모리는 JVM에 의해 관리됩니다. JVM에는 매우 성숙한 가비지 수집 기능이 있습니다. 가비지 수집은 항상 하나 이상의 스레드에서 실행됩니다. 즉, 작업자 스레드와 병렬로 실행되거나 때로는 이러한 작업자 스레드를 일시 중지하여 도달할 수 없는 개체를 표시하고 지우고 감지된 메모리 개체를 분산시킵니다. 함께. 걱정해야 할 것은 성능뿐입니다.

Go 언어도 이 방법을 사용하지만 여전히 미묘한 차이가 있습니다. Go 언어에는 참조가 없지만 포인터가 있습니다. 이 차이는 매우 중요합니다. Go 언어는 추가 C 코드와 통합될 수 있습니다. 성능상의 이유로 런타임에는 참조와 같이 등록된 것이 없습니다. 실제 포인터는 실행 중인 시스템에 투명합니다. 할당된 메모리를 분석하여 연결 가능성 정보를 수집할 수 있으며 사용되지 않은 개체를 표시하고 지울 수는 있지만 압축을 위해 메모리를 다른 곳으로 이동할 수는 없습니다.

Go 언어에는 가비지 컬렉션이 있지만 메모리를 압축하지 않기 때문에 Java와 같은 전체 GC가 아닙니다. 이것이 반드시 나쁜 것은 아닙니다. 이는 서버가 메모리 조각화를 일으키지 않고 오랫동안 실행되는 데 적합하기 때문입니다. 일부 JVM 가비지 수집기는 이전 세대를 지울 때 GC 일시 중지를 줄이기 위해 압축 단계를 건너뛰고 최후의 수단으로만 압축을 사용합니다. Go에는 이 최후의 수단 단계가 구현되지 않아 일부 드문 시나리오에서 문제가 발생할 수 있습니다. 이 언어를 배우면 이런 문제가 발생할 가능성이 거의 없습니다.

로컬 변수

Java 언어에서는 로컬 변수(때때로 최신 버전의 객체)가 스택에 저장됩니다. 이는 호출 스택 자체를 구현하는 C, C++ 및 기타 언어에서도 마찬가지입니다. 단순히 함수에서 지역 변수에 대한 포인터를 반환하지 않는 한 Go도 예외는 아닙니다. 이는 C 언어의 치명적인 오류입니다. Go의 경우 Go 컴파일러는 할당된 "객체"(여기서 따옴표가 사용되는 이유는 나중에 설명하겠습니다)가 메서드에서 탈출한 것을 찾아 그에 따라 해당 객체(메모리)를 할당하므로 이 "객체"는 함수에 아직 살아 있습니다. 반환 후 포인터는 신뢰할 수 없는 데이터가 있는 쓸모 없는 메모리를 가리키지 않습니다.

Closure

함수형 언어처럼 함수 내부에 함수를 작성한 다음 이 함수를 반환할 수 있습니다(Go 언어는 함수형 언어입니다). 이 함수의 지역 변수는 클로저 변수입니다.

함수 반환 값

함수는 단일 값뿐만 아니라 여러 값도 반환할 수 있습니다. 이는 공정한 사용이 없는 나쁜 관행처럼 보입니다. 이는 Python과 Perl 모두에 해당됩니다. 여러 값을 반환하는 것은 어떤 상황에서는 유용합니다. 주로 반환 값과 'nil' 또는 오류 코드에 사용됩니다. 이런 식으로 오류를 반환 유형으로 인코딩하던 과거 습관(보통 C 표준 라이브러리 호출과 같이 오류 코드로 -1을 반환하고 다른 의미를 나타내는 음수가 아닌 값을 반환함)은 더 읽기 쉬운 이 방법으로 대체됩니다. .

객체 지향

클로저와 함수를 일급 시민으로 처리함으로써 Go는 최소한 JavaScript만큼 객체 지향적일 수 있습니다. 그러나 실제로 Go에는 인터페이스와 구조가 있으며 더 많은 작업을 수행할 수 있습니다. 그러나 인터페이스와 구조체는 실제 클래스가 아니며 값 유형입니다. 값으로 전달되며, 메모리 내 어디에 저장되어 있든 상관없이 저장하는 데이터는 객체 헤더나 객체 헤더와 같은 것이 없는 순수한 데이터일 뿐입니다. Go의 구조체는 C의 구조체와 매우 유사합니다. 둘 다 필드를 포함할 수 있지만 서로 상속하거나 메서드를 포함할 수는 없습니다. 객체 지향 구현은 약간 다릅니다.

메서드를 클래스 정의에 넣기보다는 메서드 자체를 정의할 때 구조체를 지정할 수 있습니다. 구조에는 다른 구조가 포함될 수도 있습니다. 참조하려는 필드에 이름이 없으면 해당 유형으로 참조할 수 있으며, 이 유형은 암시적으로 필드 이름이 됩니다. 또는 이 필드나 메소드가 최상위 구조에 속하는 한 참조할 수 있습니다

메서드를 호출할 수 있는 구조를 지정하려면 구조를 통해 직접 지정하거나 해당 구조에 대한 포인터를 가리킬 수 있습니다. 구조. 메서드가 구조체에 적용되면 메서드는 호출 구조체(값으로 전달됨)의 복사본을 가져옵니다. 메서드가 구조체에 대한 포인터에 적용되면 포인터가 전달됩니다(참조로 전달하는 것과 유사). 후자의 경우 메서드는 구조체를 변경할 수도 있습니다(이 의미에서 값 유형은 변경할 수 없으므로 구조체는 값 유형이 아닙니다). 둘 다 인터페이스의 요구 사항을 충족하는 데 사용될 수 있습니다.

Go의 구문은 구조와 포인터에 더 관대해야 합니다. C에서는 b.a를 사용하여 소유한 구조체의 a 필드에 액세스할 수 있습니다. C의 구조에 대한 포인터의 경우 b->a를 사용하여 동일한 필드에 액세스해야 합니다. b.a는 포인터를 사용할 때 오류를 보고합니다. Go는 b->a를 쓰는 것이 의미가 없다고 생각합니다(그렇습니다). .연산자가 오버로드될 수 있는데 왜 -> 연산자로 인해 코드가 복잡해 보이나요? 구조는 이러한 방식으로 필드에 액세스할 수 있으므로 포인터를 통해서도 이러한 방식으로 액세스해야 합니다. 이는 매우 논리적입니다.

타입이 객체가 아닌 변수에 있습니다

그래서 "객체" 주위에 따옴표를 붙였습니다. Go가 구조를 저장할 때 이는 객체 헤더가 없습니다. 실제로 변수에는 값 유형이 포함됩니다. 변수가 구조 유형인 경우 컴파일 타임에 이미 알고 있습니다. 변수가 인터페이스 유형인 경우 변수는 해당 값을 가리키고 값의 실제 유형을 참조합니다.

인터페이스 구현

Go에서 인터페이스는 매우 간단하면서도 동시에 매우 복잡합니다. 인터페이스는 인터페이스와 호환되기를 원하는 경우 구조가 구현해야 하는 여러 메서드를 선언합니다. 인터페이스 상속은 구조체 상속과 동일합니다. 이상한 점은 구조체가 인터페이스를 구현할 때 이를 명시적으로 지정할 필요가 없다는 것입니다. 실제로 인터페이스를 구현하는 것은 인터페이스가 아니라 구조 또는 구조에 대한 포인터를 수신자로 사용하는 함수 세트입니다. 인터페이스의 모든 기능이 구현되면 이 구조가 인터페이스를 구현합니다. 일부 기능이 구현되지 않으면 구현이 불완전합니다.

Java에서는 'implements' 키워드가 필요하지만 Go에서는 필요하지 않은 이유는 무엇입니까? Go에는 완전히 컴파일되어 있고 런타임 중에 컴파일된 코드를 별도로 로드하는 Java와 같은 클래스 로더가 없기 때문에 실제로 필요하지 않습니다. 구조체가 인터페이스를 구현해야 하지만 그렇지 않은 경우 이는 컴파일 타임에 발견되며 인터페이스가 인터페이스를 구현하는지 여부를 명시적으로 표시할 필요가 없습니다. Go의 리플렉션을 사용하여 이를 구현할 수 있는데, 그러면 런타임 오류가 발생하지만 어떤 경우에도 'implements' 키워드 선언은 효과가 없습니다.

스레드와 큐

Go 언어에는 스레드와 큐가 내장되어 있습니다. 이를 코루틴과 채널이라고 합니다. 코루틴을 시작하려면 다른 스레드에서 시작될 go 함수 call()을 작성하면 됩니다. Go 표준 라이브러리에는 "객체"를 잠그는 방법이나 기능이 있지만 기본 다중 스레드 프로그래밍은 채널을 사용합니다. 채널은 Go에 내장된 유형으로, 다른 모든 유형의 고정 크기 선입선출 채널입니다. 값을 채널에 푸시하면 코루틴이 채널에서 값을 가져올 수 있습니다. 채널이 가득 차면 밀면 차단되고, 채널이 비어 있으면 당기면 차단됩니다.

Go에는 오류가 있지만 예외는 없습니다

Go에는 실제로 예외 처리 기능이 있지만 Java처럼 사용되지는 않습니다. 예외는 '패닉'이라고 하며 코드에 실제 패닉이 발생할 때 사용됩니다. Java 규칙의 관점에서 'panic'은 '...Error'로 끝나는 일부 예외와 유사합니다. 이 상태는 처리할 수 있는 예외 인스턴스나 오류가 있을 때 시스템 호출에 의해 반환되며, 애플리케이션 함수는 유사한 패턴으로 이 상태를 처리할 것으로 예상됩니다.

마지막은 없고, 연기하여 대체합니다

강하게 결합된 예외 처리는 Java가 try/catch/finally 기능과 함께 구현하는 기능입니다. Java에서는 finally 블록에 무슨 일이 있어도 실행될 코드를 넣을 수 있습니다. Go는 메서드가 반환되기 전에 호출할 함수를 지정할 수 있는 'defer' 키워드를 제공합니다(메서드가 패닉이 발생하더라도). 위의 문제를 해결하기 위해 Defer를 사용하면 남용 가능성이 줄어듭니다. 지연된 함수 호출 후에는 실행 가능한 코드를 작성할 수 없습니다. 그러나 Java에서는 finally 블록에 return 문을 작성할 수도 있고 finally 블록에서 실행될 코드를 처리하는 데 사용되는 매우 혼란스러운 try 문을 볼 수도 있으며, 이로 인해 예외가 발생할 수도 있습니다. Go는 전자를 선호합니다.

전반적으로 Go는 흥미로운 언어입니다. 이는 언어 수준에서도 Java를 대체하지 않습니다. Java와 Go는 동일한 유형의 작업을 제공하지 않습니다. Java는 엔터프라이즈 수준 개발 언어이고 Go는 시스템 수준 프로그래밍 언어입니다.

추천 Java 동영상 튜토리얼: JAVA 동영상 튜토리얼

추천 Go 동영상 튜토리얼: go 동영상 튜토리얼#🎜 🎜#

위 내용은 PHP를 go 또는 java로 변환하시겠습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.