programing

신속한 언어로 구조화 vs 클래스

linuxpc 2023. 4. 16. 14:42
반응형

신속한 언어로 구조화 vs 클래스

Apple의 책 "구조와 클래스의 가장 중요한 차이점 중 하나는 구조가 코드로 전달될 때 항상 복사되지만 클래스는 참조로 전달된다는 것입니다."

그게 무슨 뜻인지 누가 좀 도와줄래?저는 계급과 구조가 같은 것 같아요.

를 들면, 이 는요, 이 예제는요.class두어떻게 해 주십시오. 이름이 변경되면 두 변수에 의해 참조되는 인스턴스가 어떻게 업데이트되는지 주의해 주십시오. Bob is금 is is이다Sue그 곳에, , , , , , , ,Bob참조된 적이 있습니다.

class SomeClass {
    var name: String
    init(name: String) {
        self.name = name
    }
}

var aClass = SomeClass(name: "Bob")
var bClass = aClass // aClass and bClass now reference the same instance!
bClass.name = "Sue"

println(aClass.name) // "Sue"
println(bClass.name) // "Sue"

, 이제 ★★★★★★★★★★★★★★★★★★★★★★」struct값이 복사되고 각 변수가 고유한 값 집합을 유지합니다.을 「」로 .Sue , . . . . . . . .Bob을 in in in in in in aStruct을 사용하다

struct SomeStruct {
    var name: String
    init(name: String) {
        self.name = name
    }
}

var aStruct = SomeStruct(name: "Bob")
var bStruct = aStruct // aStruct and bStruct are two structs with the same value!
bStruct.name = "Sue"

println(aStruct.name) // "Bob"
println(bStruct.name) // "Sue"

「」가 .class일 경우, A는 관련 데이터의 측정값이나 비트값입니다.struct따라서 부작용 없이 쉽게 복사하여 계산하거나 값을 수정할 수 있습니다.

클래스 및 구조 모두 다음 작업을 수행할 수 있습니다.

  • 값을 저장할 속성 정의
  • 기능을 제공하는 방법을 정의합니다.
  • 연장되다
  • 프로토콜 준수
  • 이니셜라이저 정의
  • 변수에 대한 액세스를 제공하는 첨자를 정의합니다.

클래스에서 할 수 있는 것은 다음뿐입니다.

  • 상속
  • 타이핑
  • 디초기화자 정의
  • 여러 참조에 대해 참조 카운트를 허용합니다.

struct값 타입입니다.즉, 구조체의 인스턴스를 다른 변수로 복사하면 해당 변수가 복사됩니다.

값 유형의 예

struct Resolution {
    var width = 2
    var height = 3
}

let hd = Resolution(width: 1920, height: 1080)
var cinema = hd //assigning struct instance  to variable
println("Width of cinema instance is \(cinema.width)")//result is 1920
println("Width of hd instance is \(hd.width)")//result is 1920

cinema.width = 2048

println("Width of cinema instance is \(cinema.width)")//result is 2048
println("Width of hd instance is \(hd.width)")//result is 1920

클래스는 참조 유형입니다.즉, 클래스의 인스턴스를 변수에 할당하면 해당 인스턴스에 대한 참조만 유지되고 복사본은 유지되지 않습니다.

스위프트 타입

  • named type ★★★★★★★★★★★★★★★★★」nominal type ★★★★★★★★★★★★★★★★★」type with name
  • compound type ★★★★★★★★★★★★★★★★★」non-nominal type ★★★★★★★★★★★★★★★★★」type without name

Value type또또 、 수수또또또alsoalso또또alsoalsoalsoalsoalsoalsoalsoalsoalsoalsoalsoalsoalsoalsoalsoalsoalsoalso(as ★★★★★★★★★★★★★★★★★」is체크는 구조의 복사본을 만듭니다.)

Reference types상수에 되어 있는 되어 있는 .

유형:

Struct,Enum[About],Tuple
struct String,struct Array )Set,Dictionary)

(표c-C)int...)

문자열 및 빌트인 컬렉션 값 유형에는 다음 항목에 대한 내부 참조가 포함됩니다.heap

  • 할당 또는 합격 value type새로운 데이터 복사본이 생성됩니다.copy on write-COW메커니즘은 일부 최적화와 함께 일부 특정 클래스(예: Collections(Array, Dictionary, Set))[About]사용됩니다(예: 객체 수정 시 복사본이 생성됩니다).커스텀 타입의 경우 COW를 직접 지원해야 합니다.
  • 인스턴스를 수정할 때 로컬 효과만 있습니다.
  • 값이 로컬 변수인 경우 스택 메모리가 사용됩니다[대략].

참조 유형:
Class,Function

(목표-C 기타 모든 것)

ARC

  • 시 패스 시reference type원래 인스턴스에 대한 새 참조가 생성됩니다(인스턴스 주소가 복사됨).
  • 인스턴스를 수정하면 인스턴스가 공유되고 해당 인스턴스를 가리키는 참조에 의해 액세스할 수 있으므로 전역 효과가 있습니다.
  • 보통 히프 메모리가 사용됩니다[대략].

여기에 이미지 설명 입력

Value type디폴트 사용을 권장합니다.가장 큰 장점Value type그들은 보통 그런 사람들이다.thread safe

Reference type

  • 유전될 수 있고
  • deinit()수 , 쓸 수 있습니다.
  • 를 비교하다=== ,
  • Objective-C: " " " 에서의 상호 운용성Value Type재빠르다

[스택 vs 힙]
[let vs var, class vs structure ]
[클래스 대 구조]

구조 및 클래스 선택
종류들
클래스 및 구조

위의 답변이 맞습니다. 제 답변이 위의 답변을 이해하지 못하는 사람에게 도움이 되었으면 합니다.

스위프트에는 두 가지 종류의 물체가 있습니다.

  1. 구조
  2. 학급

그 둘의 주요 차이점은

  • 구조는 값 유형입니다.
  • 클래스가 참조 유형입니다.

예를 들어, 여기에 잘 이해하기 위한 코드가 있습니다.

struct SomeStruct {
var a : Int;

init(_ a : Int) {
    self.a = a
}
}

class SomeClass {
var a: Int;

init(_ a: Int) {
    self.a = a
}

}
var x = 11

var someStruct1 = SomeStruct(x)
var someClass1 = SomeClass(x)

var someStruct2 = someStruct1
var someClass2 = someClass1

someClass1.a = 12
someClass2.a // answer is 12 because it is referencing to class 1     property a

someStruct1.a = 14
someStruct2.a // answer is 11 because it is just copying it not referencing it

이것이 주된 차이였지만 우리는 하위 차이도 있다.

학급

  1. 이니셜라이저(컨스트럭터)를 선언해야 합니다.
  2. 디초기화자 있음
  3. 다른 클래스에서 상속 가능

구조

  1. 여기에는 무료 이니셜라이저가 포함되어 있습니다. 무료 이니셜라이저를 사용하는 경우 이니셜라이저를 선언한 이니셜라이저가 덮어쓰게 됩니다.
  2. 초기화 해제 기능 없음
  3. 다른 구조에서 상속할 수 없습니다.

이 질문은 중복되는 것 같지만, 그 사용 사례의 대부분은 다음과 같습니다.

  1. 구조와 클래스의 가장 중요한 차이점 중 하나는 구조가 값 유형이며 코드 내에서 전달될 때 항상 복사되고 클래스는 참조 유형이며 참조에 의해 전달된다는 것입니다.

  2. 또한 클래스에는 하나의 클래스가 다른 클래스의 특성을 상속할 수 있는 상속 기능이 있습니다.

  3. 구조 속성은 스택에 저장되고 클래스 인스턴스는 힙에 저장되므로 스택이 클래스보다 훨씬 빠를 수 있습니다.

  4. 구조체는 기본 이니셜라이저를 자동으로 가져오지만 클래스에서는 초기화해야 합니다.

  5. 구조는 임의의 시점에서 스레드 세이프 또는 싱글톤입니다.

또한 구조와 세분류의 차이를 요약하기 위해서는 가치와 기준 유형의 차이를 이해할 필요가 있다.

  1. 값 유형의 복사본을 만들면 복사 중인 데이터의 모든 데이터가 새 변수로 복사됩니다.둘 다 별개의 것으로, 한쪽을 변경해도 다른 쪽에는 영향을 주지 않습니다.
  2. 참조 타입의 카피를 작성하면, 새로운 변수는 카피하고 있는 것과 같은 메모리 위치를 참조합니다.즉, 둘 다 같은 메모리 위치를 가리키기 때문에 하나를 변경하면 다른 하나가 변경됩니다.아래의 샘플 코드를 참조할 수 있습니다.

// 샘플 놀이터.놀이터.

  class MyClass {
        var myName: String
        init(myName: String){
            self.myName = myName;
        }
    }

    var myClassExistingName = MyClass(myName: "DILIP")
    var myClassNewName = myClassExistingName
    myClassNewName.myName = "John"


    print("Current Name: ",myClassExistingName.myName)
    print("Modified Name", myClassNewName.myName)

    print("*************************")

    struct myStruct {
        var programmeType: String
        init(programmeType: String){
            self.programmeType = programmeType
        }
    }

    var myStructExistingValue = myStruct(programmeType: "Animation")
    var myStructNewValue = myStructExistingValue
    myStructNewValue.programmeType = "Thriller"

    print("myStructExistingValue: ", myStructExistingValue.programmeType)
    print("myStructNewValue: ", myStructNewValue.programmeType)

출력:

Current Name:  John
Modified Name John
*************************
myStructExistingValue:  Animation
myStructNewValue:  Thriller

Apple 핸드북을 자세히 보면 "구조 및 열거는 값 유형입니다" 섹션을 볼 수 있습니다.

이 섹션에서는 다음과 같이 설명합니다.

"let hd = Resolution (폭: 1920, 높이: 1080) var cinema = hd 이 예에서는 hd라는 상수를 선언하고 풀 HD 비디오의 폭과 높이로 초기화된 해상도 인스턴스로 설정합니다.

그런 다음 cinema라는 변수를 선언하고 현재 hd 값으로 설정합니다.해상도는 구조이기 때문에 기존 인스턴스의 복사본이 만들어지고 이 새 복사본이 시네마에 할당됩니다.hd와 cinema는 현재 폭과 높이가 같지만 이면에는 전혀 다른 두 가지 예가 있습니다.

다음으로, 시네마의 폭 속성을 디지털 시네마 투영에 사용되는 약간 더 넓은 2K 규격의 폭(2048픽셀, 높이 1080픽셀)으로 수정한다.

시네마width = 2048 시네마의 너비 속성을 확인하면 실제로 2048로 변경되었음을 알 수 있습니다.

println은 지금(syslog)입니다.width) pixels width") // "cinema width"를 인쇄합니다. 그러나 원래 hd 인스턴스의 width 속성은 이전 값인 1920:

printlnhd는 정지상태입니다(hdwidth) 픽셀 폭) // "hd는 아직 1920픽셀 폭"을 출력합니다.

cinema에 hd의 현재 값이 주어졌을 때 hd에 저장된 값이 새로운 cinema 인스턴스에 복사되었습니다.결과적으로 완전히 다른 두 인스턴스가 생성되고, 이 인스턴스는 우연히 같은 숫자 값을 포함합니다.개별 인스턴스이기 때문에 영화 너비를 2048로 설정해도 HD로 저장되는 너비에 영향을 주지 않습니다.

출처: Apple Inc.에서 발췌.'스위트 프로그래밍 언어' 아이북스https://itun.es/us/jEUH0.l

이것이 구조와 클래스의 가장 큰 차이입니다.구조가 복사되고 클래스가 참조됩니다.

에서) 힙에 되어 있는 그 후, 참조(포인터)에는, 「」(」( 「포인터」)가 되어 있습니다.name를 사용하여 이러한 데이터 블록에 액세스합니다.이 메커니즘에서는 참조(포인터) 값을 복사하여 힙 내의 개체를 공유할 수 있습니다.이는 정수 등의 기본 데이터 유형의 경우가 아니며, 이는 참조를 작성하기 위해 필요한 메모리가 개체(이 경우 정수 값)와 거의 동일하기 때문입니다.따라서 큰 객체의 경우 참조가 아닌 값으로 전달됩니다.

Swift는 String 객체와 Array 객체에서도 성능을 향상시키기 위해 구조를 사용합니다.

여기 정말 좋은 읽을거리야

구조와 클래스의 차이를 이해하기 위해서는 값과 참조 유형의 주요 차이를 알아야 합니다.구조체는 값 유형입니다. 즉, 구조체의 모든 변경은 해당 값만 수정하고 클래스는 참조 유형이며 참조 유형이 변경될 때마다 해당 메모리 또는 참조 위치에 할당된 값이 수정됩니다.예를 들어 다음과 같습니다.

부터 시작하겠습니다는 예를 할 수 .이를 만듭니다이 클래스는 인스턴스를 비교할 수 있도록 Equatable에 준거하고 있습니다.이 클래스는pointClassInstanceA는 「」라고 불리고 있습니다.pointClassInstanceB클래스 A를 클래스 B에 할당하면, 이제 어설션에서는 같은 것으로 되어 있습니다.

class PointClass: Equatable {
    var x: Double
    var y: Double

    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }

    static func == (lhs: PointClass, rhs: PointClass) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}

var pointClassInstanceA = PointClass(x: 0, y: 0)
var pointClassInstanceB = pointClassInstanceA

assert(pointClassInstanceA==pointClassInstanceB) 

pointClassInstanceB.x = 10
print(pointClassInstanceA.x)
//this prints 10

여기서 pointsClassInstanceB의 x 값을 변경하면 pointClassInstanceA의 x 값도 변경되는 이유는 무엇입니까?예를 들어 인스턴스 A를 인스턴스 B의 값으로 할당하고 그 중 하나의 X를 수정하면 두 X가 모두 변경됩니다.두 X는 같은 참조를 공유하기 때문입니다.또, 변경된 것은 그 참조의 값입니다.

똑같이 하자, 하지만 구조를 가지고.

struct PointStruct: Equatable {
    var x: Double
    var y: Double

    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }

    static func == (lhs: PointStruct, rhs: PointStruct) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}
var pointStructInstanceA = PointStruct(x: 0, y: 0)
var pointStructInstanceB = pointStructInstanceA

assert(pointStructInstanceA==pointStructInstanceB)
pointStructInstanceB.x = 100
print(pointStructInstanceA.x)
//this will print 0

기본적으로는 클래스와 같은 구조를 가지고 있습니다만, 이 케이스에서는 pointStructInstanceA의 x 값을 출력해도 변경되지 않습니다.이는 값 타입이 다르게 동작하기 때문입니다.인스턴스의 모든 변경은 "독립"되어 다른 인스턴스에 영향을 주지 않습니다.

Swift는 더 많은 값 유형을 사용할 것을 권장합니다.또한 참조 유형이 의도하지 않게 값을 수정하는 등의 문제를 피하기 위해 라이브러리가 구조에 기반하고 있음을 알 수 있습니다.구조물이 스위프트로 가는 길이다.도움이 됐으면 좋겠다.

여기 구조와 클래스의 차이를 정확하게 보여주는 예가 있습니다.

놀이터에서 작성된 코드 스크린샷
놀이터에서 작성된 코드 스크린샷

struct Radio1{
    var name:String
    //    init(name:String) {
    //        self.name = name
    //    }
}

struct Car1{
    var radio:Radio1?
    var model:String

}

var i1 = Car1(radio: Radio1(name:"murphy"),model:"sedan")
var i2 = i1
//since car instance i1 is a struct and 
//this car has every member as struct ,
//all values are copied into i2

i2.radio?.name //murphy
i2.radio = Radio1(name: "alpha")
i2.radio?.name //alpha

i1.radio?.name //murphy

//since Radio1 was struct , 
//values were copied and thus
// changing name  of instance of Radio1 in i2 
//did not bring change in i1

class Radio2{
    var name:String
    init(name:String) {
        self.name = name
    }
}

struct Car2{
    var radio:Radio2?
    var model:String

}
var i3 = Car2(radio: Radio2(name:"murphy"),model:"sedan")
//var radioInstance = Radio2(name: "murphy")
//var i3 = Car2(radio: radioInstance,model:"sedan")

var i4 = i3
//since i3 is instance of struct
//everything is copied to i4 including reference of instance of Radio2
//because Radio2 is a class



i4.radio?.name //murphy
i4.radio?.name="alpha"
i4.radio?.name //alpha

i3.radio?.name //alpha

//since Radio2 was class, 
//reference was copied and 
//thus changing name of instance 
//of Radio2 in i4 did  bring change in i3 too


//i4.radio?.name
//i4.radio = Radio2(name: "alpha")
//i4.radio?.name
//
//i3.radio?.name
1.structure is value type.
   = > when we assign structure variable to other variable or pass as parameter to function, it creates separate/new copy => so that changes made on one variable does not  reflect on another.[We can say like **call by value** concept] 
Example :

    struct DemoStruct 
    { 
        var value: String 
        init(inValue: String) 
        { 
            self.value = inValue 
        } 
    } 


var aStruct = DemoStruct(inValue: "original") 
var bStruct = aStruct // aStruct and bStruct are two structs with the same value! but references to diff location`enter code here`
bStruct.value = "modified" 

print(aStruct.value) // "original" 
print(bStruct.value) // "modified"


2.class is reference type.
 = > when we assign structure variable to other variable or pass as parameter to function, it **does not** creates separate/new copy => so that changes made on one variable does not  reflect on another.[We can say like **call by reference** concept] 
Example:
class DemoClass 
{   
    var value: String 
    init(inValue: String) 
    {
        self.value = inValue 
    } 
} 

var aClass = DemoClass(inName: "original") 
var bClass = aClass // aClass and bClass now reference the same instance! 
bClass.value = "modified" 

print(aClass.value) // "modified" 
print(bClass.value) // "modified"

많은 사람들이 이미 복사 구조와 클래스의 차이점에 대해 지적했듯이, 그것은 모두 c의 어디에서 왔는지 이해할 수 있습니다.

struct A {
    let a: Int
    let c: Bool
}

func 부모 오브젝트 또는 구조에 로컬 메모리에서는 다음과 같습니다.

64bit for int
8 bytes for bool

자, 이제

class A {
    let a: Int
    let c: Bool
}

로컬 메모리, 구조 또는 클래스에 저장되는 데이터 내용 대신 단일 포인터가 될 것입니다.

64bit address of class A instance

차이점을 쉽게 알 수 있는 2개의 복사, 첫 번째 복사, int용 64비트 복사, bool용 8비트 복사, 클래스 A의 인스턴스에 64비트주소를 복사하면 같은 메모리주소의 여러 복사를 모두 같은 인스턴스를 가리킬 수 있습니다.구조의 각 복사본은 자체 복사본이 될 것입니다.

이제 복잡한 일이 생길 수 있어요 두 가지를 섞어서

struct A {
    let a: ClassA
    let c: Bool
}

당신의 기억은 마치

64bit address of class A instance
8 bytes for bool

프로그램에 구조체의 복사본이 여러 개 있어도 모두 동일한 객체 ClassA에 대한 복사본이 있기 때문에 이는 인스턴스 ClassA에 대한 참조가 여러 개 있는 경우와 마찬가지로 오브젝트에 대한 참조 수를 유지해야 삭제 시기를 알 수 있기 때문입니다.프로그램에서는 클래스 A 인스턴스에 대한 참조 카운트를 유지해야 하는 구조 A에 대한 참조를 여러 개 가질 수 있습니다.구조물에 클래스가 많거나 포함된 구조물에 클래스가 많으면 이 작업은 시간이 걸릴 수 있습니다.구조물을 복사할 때,컴파일러는 당신의 구조 및 하위구조에서 참조되는 모든 클래스 인스턴스를 통과하는 코드를 생성하고 참조 카운트를 증가시켜 얼마나 많은 참조가 있는지 추적해야 합니다.이렇게 하면 단일 주소만 복사하면 되기 때문에 클래스가 훨씬 빠르게 전달될 수 있으며, 자체 참조 수가 0이 될 때까지 포함된 모든 하위 항목의 참조 수를 줄일 수 있기 때문에 하위 항목의 참조 수를 늘릴 필요가 없습니다.

Apple의 일부 구조 유형에는 객체 유형이 실제로 포함되어 있기 때문에 더욱 복잡해집니다.참조되는 데이터의 장점은 메모리에 저장하여 자유롭게 늘릴 수 있다는 것입니다.또한 로컬 스택에 저장되어 있는 데이터와는 달리 매우 클 수 있습니다.String, Array, Set 등의 유형도 있습니다.사전은 구조체처럼 동작하며 모든 항목을 변경하지 않도록 수정하려고 하면 내부 데이터의 복제도 만들 수 있지만, 여전히 참조 데이터가 카운트되어야 하며, 따라서 이러한 유형의 많은 부분을 포함하는 구조체는 각 유형의 내부 데이터가 유지되어야 하기 때문에 여전히 느릴 수 있습니다.

물론 구조 유형을 전달하면 많은 오류가 발생할 가능성을 줄일 수 있지만, 포함된 유형에 따라 프로그램 속도가 느려질 수도 있습니다.

이것에 대해 많은 것이 쓰여져 있습니다만, 거기에 비유를 더하고 싶습니다.그 후로는 의심의 여지가 없기를 바랍니다.결론: 클래스는 참조에 의해 통과되고 구조물은 값에 의해 통과됩니다.

Google 문서 시트를 친구와 공유하고 있다고 가정합니다.여기서 그가 무언가를 변경하면, 당신은 당신의 구글 문서에도 변화가 있다는 것을 알게 될 것입니다. 이는 당신의 복사본도 영향을 받는다는 것을 의미합니다.기본적으로 "참고로 통과"입니다.

하지만 만약 당신이 .X를 가지고 있다면LS fie가 컴퓨터에 저장되었습니다.당신은 그 파일을 친구에게 제공합니다.이제 그가 그 파일을 변경하더라도, 당신은 당신의 복사본을 가지고 있기 때문에 당신의 파일은 엉망이 되거나 영향을 받지 않습니다.이는 기본적으로 "가치로 통과"됩니다.빠른 놀이터에서 이러한 유사성을 확인할 수 있는 간단한 프로그램이 이미 여러 개 있습니다.

언급URL : https://stackoverflow.com/questions/24217586/structure-vs-class-in-swift-language

반응형