Tại sao lại dùng struct thay vì class c

Tôi đang tham gia một lớp học về Lập trình hướng đối tượng trong C ++. Trong một nhiệm vụ gần đây, tôi đã xác định một chức năng thành viên trong a struct. Người hướng dẫn của tôi giải thích rằng, mặc dù có thể biên dịch để sử dụng các hàm thành viên trong các cấu trúc, nhưng ông ấy muốn chúng tôi không làm như vậy, vì khả năng tương thích ngược với C và (đặc biệt là trong lớp dành cho người mới bắt đầu này) để thực hành đóng gói dữ liệu tốt - chúng ta nên sử dụng a structcho các loại chứa chủ yếu là dữ liệu và classdành cho các ứng dụng được hưởng lợi từ việc đóng gói theo thủ tục nhiều hơn. Anh ấy chỉ ra rằng thực tiễn này xuất phát từ lịch sử của các cấu trúc / lớp trong C ++, đó là điều tôi muốn biết thêm.

Tôi biết rằng cấu trúc có chức năng giống như các lớp ngoại trừ quyền truy cập thành viên / kế thừa mặc định. Câu hỏi của tôi là:

Tại sao các lớp cấu trúc AND được bao gồm trong C ++? Từ nền tảng của tôi về C #, nơi cấu trúc và lớp có những khác biệt quan trọng, có vẻ như structtrong C ++ chỉ là một đường cú pháp để xác định các lớp với public-ness mặc định. Là nó?

Tôi không tìm kiếm ý kiến về việc khi nào / tại sao nên sử dụng một cái này thay vì cái kia- Tôi sinh ra tốt sau những cấu trúc này, và tôi đang tìm kiếm lịch sử của chúng. Họ đã được thụ thai cùng nhau? Nếu vậy, tại sao? Nếu không, cái nào đến trước và tại sao cái thứ hai được thêm vào? Tôi nhận thấy rằng có rất nhiều người lớn tuổi đáng kính trong cộng đồng này, những người có thể còn nhớ về nguồn gốc của các tính năng này và các liên kết đến các ấn phẩm tiêu chuẩn, hoặc ví dụ về mã, nơi cả hai, một hoặc khác xuất hiện lần đầu tiên, sẽ bổ sung thêm cho sự hữu ích của câu trả lời .

Xin lưu ý, câu hỏi này không phải là :

6/15/2014 6:33:02 PM

Tại sao lại dùng struct thay vì class c

Trần Lộc An · Trần Lộc An 18:33 15/06/2014

Chơi xung quanh với Swift, đến từ nền Java, tại sao bạn muốn chọn Struct thay vì Class? Có vẻ như chúng giống nhau, với Struct cung cấp ít chức năng hơn. Tại sao chọn nó sau đó?

  • swift
  • class
  • struct
  • design-principles

432 hữu ích 5 bình luận 133k xem chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Phan Diễm Phương · Phan Diễm Phương 18:37 15/06/2014

Theo Chương trình định hướng giao thức nói chuyện WWDC 2015 rất phổ biến trong Swift ( video , bảng điểm ), Swift cung cấp một số tính năng giúp cấu trúc tốt hơn các lớp trong nhiều trường hợp.

Cấu trúc được ưu tiên hơn nếu chúng tương đối nhỏ và có thể ghép được vì sao chép an toàn hơn nhiều so với việc có nhiều tham chiếu đến cùng một thể hiện như xảy ra với các lớp. Điều này đặc biệt quan trọng khi chuyển xung quanh một biến sang nhiều lớp và / hoặc trong môi trường đa luồng. Nếu bạn luôn có thể gửi một bản sao của biến của bạn đến những nơi khác, bạn không bao giờ phải lo lắng về nơi khác thay đổi giá trị của biến bên dưới bạn.

Với Structs, sẽ không cần phải lo lắng nhiều về việc rò rỉ bộ nhớ hoặc nhiều luồng chạy đua để truy cập / sửa đổi một thể hiện của một biến. .

Các lớp cũng có thể trở nên cồng kềnh vì một lớp chỉ có thể kế thừa từ một siêu lớp duy nhất. Điều đó khuyến khích chúng ta tạo ra những chiếc siêu xe khổng lồ bao gồm nhiều khả năng khác nhau chỉ liên quan một cách lỏng lẻo. Sử dụng các giao thức, đặc biệt là với các phần mở rộng giao thức nơi bạn có thể cung cấp các triển khai cho các giao thức, cho phép bạn loại bỏ sự cần thiết của các lớp để đạt được loại hành vi này.

Bài nói chuyện đưa ra các kịch bản trong đó các lớp được ưu tiên:

  • Sao chép hoặc so sánh các trường hợp không có ý nghĩa (ví dụ: Window)
  • Tuổi thọ của cá thể được gắn với các hiệu ứng bên ngoài (ví dụ: Tệp tạm thời)
  • Các thực thể chỉ là "chìm" - ống dẫn chỉ ghi vào trạng thái bên ngoài (egCGContext)

Nó ngụ ý rằng các cấu trúc nên là mặc định và các lớp nên là một dự phòng.

Mặt khác, tài liệu Ngôn ngữ lập trình Swift có phần mâu thuẫn:

Các thể hiện cấu trúc luôn được truyền theo giá trị và các thể hiện của lớp luôn được truyền bằng tham chiếu. Điều này có nghĩa là chúng phù hợp với các loại nhiệm vụ khác nhau. Khi bạn xem xét các cấu trúc dữ liệu và chức năng mà bạn cần cho một dự án, hãy quyết định xem mỗi cấu trúc dữ liệu nên được xác định là một lớp hay là một cấu trúc.

Theo nguyên tắc chung, hãy xem xét việc tạo cấu trúc khi áp dụng một hoặc nhiều điều kiện sau:

  • Mục đích chính của cấu trúc là gói gọn một vài giá trị dữ liệu tương đối đơn giản.
  • Thật hợp lý khi hy vọng rằng các giá trị được đóng gói sẽ được sao chép thay vì được tham chiếu khi bạn gán hoặc chuyển xung quanh một thể hiện của cấu trúc đó.
  • Bất kỳ thuộc tính nào được lưu trữ bởi cấu trúc đều là các loại giá trị, chúng cũng được dự kiến ​​sẽ được sao chép thay vì được tham chiếu.
  • Cấu trúc không cần kế thừa các thuộc tính hoặc hành vi từ một loại hiện có khác.

Ví dụ về các ứng cử viên tốt cho các cấu trúc bao gồm:

  • Kích thước của hình dạng hình học, có lẽ gói gọn một thuộc tính chiều rộng và thuộc tính chiều cao, cả hai loại Double.
  • Một cách để tham chiếu đến các phạm vi trong một chuỗi, có lẽ gói gọn một thuộc tính bắt đầu và thuộc tính độ dài, cả hai loại Int.
  • Một điểm trong hệ tọa độ 3D, có lẽ gói gọn các thuộc tính x, y và z, mỗi thuộc tính Double.

Trong tất cả các trường hợp khác, hãy định nghĩa một lớp và tạo các thể hiện của lớp đó để được quản lý và chuyển qua tham chiếu. Trong thực tế, điều này có nghĩa là hầu hết các cấu trúc dữ liệu tùy chỉnh phải là các lớp, không phải các cấu trúc.

Ở đây có tuyên bố rằng chúng ta nên mặc định sử dụng các lớp và chỉ sử dụng các cấu trúc trong các trường hợp cụ thể. Cuối cùng, bạn cần hiểu hàm ý của các loại giá trị trong thế giới thực so với các loại tham chiếu và sau đó bạn có thể đưa ra quyết định có căn cứ về thời điểm sử dụng cấu trúc hoặc các lớp. Ngoài ra, hãy nhớ rằng các khái niệm này luôn phát triển và Tài liệu Ngôn ngữ lập trình Swift đã được viết trước khi bài nói chuyện Lập trình hướng giao thức được đưa ra.

505 hữu ích 5 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Trịnh Chính Thuận · Trịnh Chính Thuận 12:22 16/06/2014

Vì các thể hiện cấu trúc được phân bổ trên ngăn xếp và các thể hiện lớp được phân bổ trên heap, các cấu trúc đôi khi có thể nhanh hơn rất nhiều.

Tuy nhiên, bạn nên luôn tự đo nó và quyết định dựa trên trường hợp sử dụng duy nhất của bạn.

Xem xét ví dụ sau, thể hiện 2 chiến lược gói Intkiểu dữ liệu bằng cách sử dụng structvà class. Tôi đang sử dụng 10 giá trị lặp lại là để phản ánh tốt hơn thế giới thực, nơi bạn có nhiều trường.

class Int10Class { let value1, value2, value3, value4, value5, value6, value7, value8, value9, value10: Int init(_ val: Int) { self.value1 = val self.value2 = val self.value3 = val self.value4 = val self.value5 = val self.value6 = val self.value7 = val self.value8 = val self.value9 = val self.value10 = val } } struct Int10Struct { let value1, value2, value3, value4, value5, value6, value7, value8, value9, value10: Int init(_ val: Int) { self.value1 = val self.value2 = val self.value3 = val self.value4 = val self.value5 = val self.value6 = val self.value7 = val self.value8 = val self.value9 = val self.value10 = val } } func + (x: Int10Class, y: Int10Class) -> Int10Class { return IntClass(x.value + y.value) } func + (x: Int10Struct, y: Int10Struct) -> Int10Struct { return IntStruct(x.value + y.value) }

Hiệu suất được đo bằng cách sử dụng

// Measure Int10Class measure("class (10 fields)") { var x = Int10Class(0) for _ in 1...10000000 { x = x + Int10Class(1) } } // Measure Int10Struct measure("struct (10 fields)") { var y = Int10Struct(0) for _ in 1...10000000 { y = y + Int10Struct(1) } } func measure(name: String, @noescape block: () -> ()) { let t0 = CACurrentMediaTime() block() let dt = CACurrentMediaTime() - t0 print("\(name) -> \(dt)") }

Mã có thể được tìm thấy tại https://github.com/knguyen2708/SturationVsClassPerformance

CẬP NHẬT (27 tháng 3 năm 2018) :

Kể từ Swift 4.0, Xcode 9.2, đang chạy Bản dựng phát hành trên iPhone 6S, iOS 11.2.6, cài đặt Trình biên dịch Swift là -O -whole-module-optimization:

  • class phiên bản mất 2.06 giây
  • struct phiên bản mất 4,17e-08 giây (nhanh hơn 50.000.000 lần)

(Tôi không còn trung bình nhiều lần chạy, vì phương sai rất nhỏ, dưới 5%)

Lưu ý : sự khác biệt là rất ít kịch tính mà không cần tối ưu hóa toàn bộ mô-đun. Tôi rất vui nếu ai đó có thể chỉ ra những gì cờ thực sự làm.

CẬP NHẬT (ngày 7 tháng 5 năm 2016) :

Kể từ Swift 2.2.1, Xcode 7.3, chạy Bản dựng phát hành trên iPhone 6S, iOS 9.3.1, trung bình trên 5 lần chạy, cài đặt Trình biên dịch Swift là -O -whole-module-optimization:

  • class phiên bản lấy 2.159942142s
  • struct phiên bản mất 5,83E-08 (nhanh hơn 37.000.000 lần)

Lưu ý : như ai đó đã đề cập rằng trong các kịch bản trong thế giới thực, có thể có nhiều hơn 1 trường trong một cấu trúc, tôi đã thêm các thử nghiệm cho các cấu trúc / lớp với 10 trường thay vì 1. Đáng ngạc nhiên, kết quả không thay đổi nhiều.

KẾT QUẢ NGUỒN GỐC (ngày 1 tháng 6 năm 2014):

(Chạy trên struct / class với 1 trường chứ không phải 10)

Kể từ Swift 1.2, Xcode 6.3.2, chạy Bản dựng phát hành trên iPhone 5S, iOS 8.3, trung bình trên 5 lần chạy

  • class phiên bản mất 9.788332333
  • struct phiên bản mất 0,010532942s (nhanh hơn 900 lần)

KẾT QUẢ OLD (từ thời gian không xác định)

(Chạy trên struct / class với 1 trường chứ không phải 10)

Với bản phát hành trên MacBook Pro của tôi:

  • Các classphiên bản mất 1,10082 giây
  • Các structphiên bản mất 0,02324 giây (50 lần nhanh hơn)

150 hữu ích 5 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Ngô Thu Ngọc · Ngô Thu Ngọc 00:03 04/03/2015

Tôi đã tạo ra ý chính cho điều này với các ví dụ đơn giản. https://github.com/objc-swift/swift-groupes-vs- cấu trúc

Và sự khác biệt

cấu trúc không thể kế thừa trong nhanh chóng. Nếu bạn muốn

class Vehicle{ } class Car : Vehicle{ }

Đi cho một lớp học.

2. Đi qua

Các cấu trúc Swift truyền theo giá trị và các thể hiện lớp chuyển qua tham chiếu.

Sự khác biệt về bối cảnh

Cấu trúc hằng và biến

Ví dụ (Được sử dụng tại WWDC 2014)

struct Point{ var x = 0.0; var y = 0.0; }

Xác định một cấu trúc gọi là Điểm.

var point = Point(x:0.0,y:2.0)

Bây giờ nếu tôi cố gắng thay đổi x. Đó là một biểu thức hợp lệ.

point.x = 5

Nhưng nếu tôi xác định một điểm là hằng số.

let point = Point(x:0.0,y:2.0) point.x = 5 //This will give compile time error.

Trong trường hợp này toàn bộ điểm là hằng số bất biến.

Nếu tôi đã sử dụng một Điểm lớp thay vì đây là một biểu thức hợp lệ. Bởi vì trong một hằng số bất biến lớp là tham chiếu đến chính lớp đó không phải là các biến thể hiện của nó (Trừ khi các biến đó được định nghĩa là hằng số)

59 hữu ích 3 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Hồ Sỹ Phú · Hồ Sỹ Phú 22:09 16/01/2015

Dưới đây là một số lý do khác để xem xét:

  1. cấu trúc có được một trình khởi tạo tự động mà bạn hoàn toàn không phải duy trì mã.

    struct MorphProperty { var type : MorphPropertyValueType var key : String var value : AnyObject enum MorphPropertyValueType { case String, Int, Double } } var m = MorphProperty(type: .Int, key: "what", value: "blah")

Để có được điều này trong một lớp, bạn sẽ phải thêm trình khởi tạo và duy trì intializer ...

  1. Các loại bộ sưu tập cơ bản như Arraylà structs. Bạn càng sử dụng chúng trong mã của riêng mình, bạn sẽ càng quen với việc chuyển theo giá trị trái ngược với tham chiếu. Ví dụ:

    func removeLast(var array:[String]) { array.removeLast() println(array) // [one, two] } var someArray = ["one", "two", "three"] removeLast(someArray) println(someArray) // [one, two, three]
  2. Rõ ràng sự bất biến so với khả năng biến đổi là một chủ đề lớn, nhưng rất nhiều người thông minh nghĩ rằng sự bất biến - cấu trúc trong trường hợp này - là thích hợp hơn. Đối tượng bất biến và bất biến

28 hữu ích 5 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Phạm Trúc Vy · Phạm Trúc Vy 02:12 25/06/2016

Giả sử rằng chúng ta biết Struct là một loại giá trị và Class là một loại tham chiếu .

Nếu bạn không biết loại giá trị và loại tham chiếu là gì thì hãy xem Sự khác biệt giữa chuyển qua tham chiếu so với chuyển qua giá trị là gì?

Dựa trên bài đăng của mikeash :

... Trước tiên hãy xem xét một số ví dụ cực kỳ rõ ràng. Số nguyên rõ ràng là có thể sao chép. Chúng nên là loại giá trị. Ổ cắm mạng không thể được sao chép hợp lý. Chúng nên là loại tham khảo. Các điểm, như trong cặp x, y, có thể sao chép. Chúng nên là loại giá trị. Một bộ điều khiển đại diện cho một đĩa không thể được sao chép hợp lý. Đó phải là một loại tài liệu tham khảo.

Một số loại có thể được sao chép nhưng nó có thể không phải là thứ bạn muốn xảy ra mọi lúc. Điều này cho thấy rằng chúng nên là loại tham khảo. Ví dụ, một nút trên màn hình về mặt khái niệm có thể được sao chép. Bản sao sẽ không hoàn toàn giống với bản gốc. Một nhấp chuột vào bản sao sẽ không kích hoạt bản gốc. Bản sao sẽ không chiếm cùng một vị trí trên màn hình. Nếu bạn chuyển nút xung quanh hoặc đặt nó vào một biến mới, bạn có thể muốn tham khảo nút gốc và bạn chỉ muốn tạo một bản sao khi được yêu cầu rõ ràng. Điều đó có nghĩa là loại nút của bạn phải là loại tham chiếu.

Bộ điều khiển xem và cửa sổ là một ví dụ tương tự. Chúng có thể được sao chép, có thể hiểu được, nhưng hầu như không bao giờ bạn muốn làm gì. Chúng nên là loại tham khảo.

Còn các kiểu mẫu thì sao? Bạn có thể có loại Người dùng đại diện cho người dùng trên hệ thống của bạn hoặc Loại Tội phạm đại diện cho một hành động được thực hiện bởi Người dùng. Đây là những bản sao đẹp, vì vậy chúng có thể là loại giá trị. Tuy nhiên, bạn có thể muốn các bản cập nhật cho Tội phạm của Người dùng được thực hiện ở một nơi trong chương trình của bạn để hiển thị cho các phần khác của chương trình. Điều này cho thấy rằng Người dùng của bạn nên được quản lý bởi một số loại bộ điều khiển người dùng sẽ là loại tham chiếu . ví dụ

struct User {} class UserController { var users: [User] func add(user: User) { ... } func remove(userNamed: String) { ... } func ... }

Bộ sưu tập là một trường hợp thú vị. Chúng bao gồm những thứ như mảng và từ điển, cũng như chuỗi. Họ có thể sao chép? Chắc chắn. Là sao chép một cái gì đó bạn muốn xảy ra dễ dàng và thường xuyên? Điều đó ít rõ ràng hơn.

Hầu hết các ngôn ngữ nói "không" với điều này và làm cho các kiểu tham chiếu bộ sưu tập của họ. Điều này đúng trong Objective-C và Java và Python và JavaScript và hầu hết mọi ngôn ngữ khác mà tôi có thể nghĩ ra. (Một ngoại lệ chính là C ++ với các loại bộ sưu tập STL, nhưng C ++ là sự điên cuồng của thế giới ngôn ngữ, thứ làm mọi thứ trở nên kỳ lạ.)

Swift nói "có", điều đó có nghĩa là các loại như Array và Dictionary và String là các cấu trúc chứ không phải là các lớp. Chúng được sao chép khi gán, và chuyển chúng dưới dạng tham số. Đây là một lựa chọn hoàn toàn hợp lý miễn là bản sao rẻ tiền, điều mà Swift rất cố gắng thực hiện. ...

Ngoài ra, không sử dụng lớp khi bạn phải ghi đè từng và mọi phiên bản của hàm, tức là chúng không có bất kỳ chức năng chia sẻ nào .

Vì vậy, thay vì có một vài lớp con của một lớp. Sử dụng một số cấu trúc phù hợp với một giao thức.

19 hữu ích 1 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Nguyễn Thành Đức · Nguyễn Thành Đức 18:38 15/06/2014

Một số ưu điểm:

  • tự động chủ đề an toàn do không thể chia sẻ
  • sử dụng ít bộ nhớ hơn do không có isa và refcount (và trên thực tế là stack được phân bổ chung)
  • các phương thức luôn được gửi tĩnh, vì vậy có thể được nội tuyến (mặc dù @final có thể làm điều này cho các lớp)
  • lý do dễ dàng hơn về (không cần "sao chép phòng thủ" như điển hình với NSArray, NSString, v.v.) vì lý do tương tự như an toàn luồng

18 hữu ích 5 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Nguyễn Vân Linh · Nguyễn Vân Linh 12:25 10/05/2016

Cấu trúc nhanh hơn nhiều so với Class. Ngoài ra, nếu bạn cần kế thừa thì bạn phải sử dụng Class. Điểm quan trọng nhất là Class là loại tham chiếu trong khi Cấu trúc là loại giá trị. ví dụ,

class Flight { var id:Int? var description:String? var destination:String? var airlines:String? init(){ id = 100 description = "first ever flight of Virgin Airlines" destination = "london" airlines = "Virgin Airlines" } } struct Flight2 { var id:Int var description:String var destination:String var airlines:String }

bây giờ cho phép tạo cá thể của cả hai.

var flightA = Flight() var flightB = Flight2.init(id: 100, description:"first ever flight of Virgin Airlines", destination:"london" , airlines:"Virgin Airlines" )

bây giờ cho phép chuyển các thể hiện này đến hai hàm sửa đổi id, mô tả, đích, v.v.

func modifyFlight(flight:Flight) -> Void { flight.id = 200 flight.description = "second flight of Virgin Airlines" flight.destination = "new york" flight.airlines = "Virgin Airlines" }

cũng thế,

func modifyFlight2(flight2: Flight2) -> Void { var passedFlight = flight2 passedFlight.id = 200 passedFlight.description = "second flight from virgin airlines" }

vì thế,

modifyFlight(flight: flightA) modifyFlight2(flight2: flightB)

Bây giờ nếu chúng tôi in id và mô tả của chuyến bay, chúng tôi sẽ nhận được

id = 200 description = "second flight of Virgin Airlines"

Ở đây, chúng ta có thể thấy id và mô tả của FlightA bị thay đổi do tham số được truyền cho phương thức sửa đổi thực sự trỏ đến địa chỉ bộ nhớ của đối tượng FlightA (kiểu tham chiếu).

bây giờ nếu chúng ta in id và mô tả về cá thể FLightB chúng ta nhận được,

id = 100 description = "first ever flight of Virgin Airlines"

Ở đây chúng ta có thể thấy rằng thể hiện của FlightB không bị thay đổi bởi vì trong phương thức redirectFlight2, thể hiện thực tế của Flight2 được truyền thay vì tham chiếu (kiểu giá trị).

12 hữu ích 4 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Dương Tuấn Hải · Dương Tuấn Hải 13:19 05/09/2016

Trả lời câu hỏi từ góc độ của các loại giá trị so với các loại tham chiếu, từ bài đăng trên blog này của Apple, nó sẽ xuất hiện rất đơn giản:

Sử dụng loại giá trị [ví dụ struct, enum] khi:

  • So sánh dữ liệu cá thể với == có ý nghĩa
  • Bạn muốn bản sao có trạng thái độc lập
  • Dữ liệu sẽ được sử dụng trong mã trên nhiều luồng

Sử dụng loại tham chiếu [ví dụ: lớp] khi:

  • So sánh danh tính cá thể với === có ý nghĩa
  • Bạn muốn tạo trạng thái chia sẻ, có thể thay đổi

Như đã đề cập trong bài viết đó, một lớp không có thuộc tính có thể ghi sẽ hoạt động giống hệt với cấu trúc, với (tôi sẽ thêm) một cảnh báo: cấu trúc là tốt nhất cho các mô hình an toàn luồng - một yêu cầu ngày càng sắp xảy ra trong kiến ​​trúc ứng dụng hiện đại.

4 hữu ích 0 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Lý Kiết Trinh · Lý Kiết Trinh 18:36 15/06/2014

Với các lớp bạn có được sự kế thừa và được truyền bằng tham chiếu, các cấu trúc không có sự kế thừa và được truyền theo giá trị.

Có những phiên WWDC tuyệt vời trên Swift, câu hỏi cụ thể này được trả lời rất chi tiết trong một trong số đó. Hãy chắc chắn rằng bạn xem những thứ đó, vì nó sẽ giúp bạn tăng tốc nhanh hơn nhiều so với hướng dẫn Ngôn ngữ hoặc iBook.

3 hữu ích 3 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Huỳnh Bảo Quốc · Huỳnh Bảo Quốc 09:06 15/06/2016

Tôi sẽ không nói rằng structs cung cấp ít chức năng hơn.

Chắc chắn, bản thân là bất biến ngoại trừ trong một chức năng đột biến, nhưng đó là về nó.

Kế thừa hoạt động tốt miễn là bạn tuân theo ý tưởng cũ tốt rằng mọi lớp nên là trừu tượng hoặc cuối cùng.

Thực hiện các lớp trừu tượng như các giao thức và các lớp cuối cùng như các cấu trúc.

Điều thú vị về cấu trúc là bạn có thể làm cho các trường của mình có thể thay đổi mà không cần tạo trạng thái có thể thay đổi được chia sẻ vì sao chép trên ghi chú quan tâm đến điều đó :)

Đó là lý do tại sao các thuộc tính / lĩnh vực trong ví dụ sau đều có thể thay đổi, mà tôi sẽ không làm trong Java hoặc C # hoặc nhanh chóng lớp .

Cấu trúc kế thừa ví dụ với một chút sử dụng bẩn và đơn giản ở phía dưới trong hàm có tên "ví dụ":

protocol EventVisitor { func visit(event: TimeEvent) func visit(event: StatusEvent) } protocol Event { var ts: Int64 { get set } func accept(visitor: EventVisitor) } struct TimeEvent : Event { var ts: Int64 var time: Int64 func accept(visitor: EventVisitor) { visitor.visit(self) } } protocol StatusEventVisitor { func visit(event: StatusLostStatusEvent) func visit(event: StatusChangedStatusEvent) } protocol StatusEvent : Event { var deviceId: Int64 { get set } func accept(visitor: StatusEventVisitor) } struct StatusLostStatusEvent : StatusEvent { var ts: Int64 var deviceId: Int64 var reason: String func accept(visitor: EventVisitor) { visitor.visit(self) } func accept(visitor: StatusEventVisitor) { visitor.visit(self) } } struct StatusChangedStatusEvent : StatusEvent { var ts: Int64 var deviceId: Int64 var newStatus: UInt32 var oldStatus: UInt32 func accept(visitor: EventVisitor) { visitor.visit(self) } func accept(visitor: StatusEventVisitor) { visitor.visit(self) } } func readEvent(fd: Int) -> Event { return TimeEvent(ts: 123, time: 56789) } func example() { class Visitor : EventVisitor { var status: UInt32 = 3; func visit(event: TimeEvent) { print("A time event: \(event)") } func visit(event: StatusEvent) { print("A status event: \(event)") if let change = event as? StatusChangedStatusEvent { status = change.newStatus } } } let visitor = Visitor() readEvent(1).accept(visitor) print("status: \(visitor.status)") }

2 hữu ích 0 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Trịnh Ngọc Nhung · Trịnh Ngọc Nhung 09:45 22/10/2017

Trong Swift, một mẫu lập trình mới đã được giới thiệu là Lập trình hướng giao thức.

Mô hình sáng tạo:

Trong swift, Struct là một loại giá trị được tự động nhân bản. Do đó, chúng tôi nhận được các hành vi cần thiết để thực hiện mẫu nguyên mẫu miễn phí.

Trong khi đó các lớp là kiểu tham chiếu, không được tự động nhân bản trong quá trình gán. Để thực hiện mẫu nguyên mẫu, các lớp phải áp dụng NSCopyinggiao thức.

Bản sao nông chỉ sao chép tham chiếu, trỏ đến các đối tượng đó trong khi sao chép sâu sao chép tham chiếu của đối tượng.

Thực hiện sao chép sâu cho từng loại tham chiếu đã trở thành một nhiệm vụ tẻ nhạt. Nếu các lớp bao gồm loại tham chiếu xa hơn, chúng ta phải triển khai mẫu nguyên mẫu cho từng thuộc tính tham chiếu. Và sau đó chúng ta phải thực sự sao chép toàn bộ biểu đồ đối tượng bằng cách thực hiện NSCopyinggiao thức.

class Contact{ var firstName:String var lastName:String var workAddress:Address // Reference type } class Address{ var street:String ... }

Bằng cách sử dụng structs và enums , chúng tôi đã làm cho mã của chúng tôi đơn giản hơn vì chúng tôi không phải thực hiện logic sao chép.

2 hữu ích 0 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Phạm Thục Nghi · Phạm Thục Nghi 11:17 17/11/2016

Nhiều API ca cao yêu cầu các lớp con NSObject, điều này buộc bạn phải sử dụng lớp. Nhưng ngoài ra, bạn có thể sử dụng các trường hợp sau từ blog Swift của Apple để quyết định nên sử dụng loại giá trị struct / enum hay loại tham chiếu lớp.

https://developer.apple.com/swift/blog/?id=10

1 hữu ích 0 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Lê Mai Anh · Lê Mai Anh 21:14 03/12/2018

Structsđang value typevà Classesđangreference type

  • Các loại giá trị nhanh hơn các loại Tham chiếu
  • Các thể hiện loại giá trị là an toàn trong môi trường đa luồng vì nhiều luồng có thể biến đổi thể hiện mà không phải lo lắng về các điều kiện cuộc đua hoặc các khóa chết
  • Loại giá trị không có tham chiếu không giống như loại tham chiếu; do đó không có rò rỉ bộ nhớ.

Sử dụng một valueloại khi:

  • Bạn muốn các bản sao có trạng thái độc lập, dữ liệu sẽ được sử dụng trong mã trên nhiều luồng

Sử dụng một referenceloại khi:

  • Bạn muốn tạo trạng thái chia sẻ, có thể thay đổi.

Thông tin thêm cũng có thể được tìm thấy trong tài liệu của Apple

https://docs.swift.org/swift-book/L LanguageGuide / C gốmAndSt Structures.html

thông tin thêm

Các loại giá trị Swift được giữ trong ngăn xếp. Trong một quy trình, mỗi luồng có không gian ngăn xếp riêng, do đó, không có luồng nào khác có thể truy cập trực tiếp vào loại giá trị của bạn. Do đó không có điều kiện chủng tộc, khóa, khóa chết hoặc bất kỳ sự phức tạp đồng bộ hóa chủ đề liên quan.

Các loại giá trị không cần phân bổ bộ nhớ động hoặc đếm tham chiếu, cả hai đều là các hoạt động đắt tiền. Đồng thời phương thức trên các loại giá trị được gửi tĩnh. Những điều này tạo ra một lợi thế rất lớn trong việc ủng hộ các loại giá trị về hiệu suất.

Xin nhắc lại ở đây là danh sách Swift

Các loại giá trị:

  • Cấu trúc
  • Enum
  • Tuple
  • Nguyên thủy (Int, Double, Bool, v.v.)
  • Bộ sưu tập (Mảng, Chuỗi, Từ điển, Bộ)

Các loại tham khảo:

  • Lớp học
  • Bất cứ điều gì đến từ NSObject
  • Chức năng
  • Đóng cửa

1 hữu ích 0 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Trịnh Ðài Trang · Trịnh Ðài Trang 12:57 19/12/2017

Một điểm không nhận được sự chú ý trong các câu trả lời này là một biến giữ một lớp so với cấu trúc có thể lettrong một thời gian vẫn cho phép thay đổi các thuộc tính của đối tượng, trong khi bạn không thể làm điều này với một cấu trúc.

Điều này hữu ích nếu bạn không muốn biến bao giờ trỏ đến một đối tượng khác, nhưng vẫn cần sửa đổi đối tượng, tức là trong trường hợp có nhiều biến đối tượng mà bạn muốn cập nhật lần lượt từng đối tượng. Nếu nó là một cấu trúc, bạn phải cho phép biến lại thành một đối tượng khác hoàn toàn bằng cách sử dụng varđể thực hiện điều này, vì một loại giá trị không đổi trong Swift đúng cho phép không có đột biến, trong khi các loại tham chiếu (các lớp) không hành xử theo cách này.

0 hữu ích 0 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Phạm Hạnh Vi · Phạm Hạnh Vi 12:35 23/05/2018

Vì struct là các loại giá trị và bạn có thể tạo bộ nhớ rất dễ dàng lưu trữ vào stack. Cấu trúc có thể dễ dàng truy cập và sau phạm vi công việc, nó dễ dàng được giải phóng khỏi bộ nhớ ngăn xếp thông qua pop từ đầu ngăn xếp. Mặt khác, lớp là kiểu tham chiếu lưu trữ trong đống và các thay đổi được thực hiện trong một đối tượng lớp sẽ tác động đến đối tượng khác vì chúng được liên kết chặt chẽ và kiểu tham chiếu. Tất cả các thành viên của cấu trúc đều công khai trong khi tất cả các thành viên của lớp là riêng tư .

Nhược điểm của struct là nó không thể được kế thừa.

0 hữu ích 0 bình luận chia sẻ

answer

Tại sao lại dùng struct thay vì class c

Võ Thy Trúc · Võ Thy Trúc 11:31 13/08/2018

  • Cấu trúc và lớp là các kiểu dữ liệu người dùng thách thức

  • Theo mặc định, cấu trúc là công khai trong khi lớp là riêng tư

  • Lớp thực hiện hiệu trưởng đóng gói

  • Các đối tượng của một lớp được tạo trên bộ nhớ heap

  • Lớp được sử dụng để tái sử dụng trong khi cấu trúc được sử dụng để nhóm dữ liệu trong cùng cấu trúc

  • Các thành viên dữ liệu cấu trúc không thể được khởi tạo trực tiếp nhưng chúng có thể được chỉ định bởi bên ngoài cấu trúc

  • Các thành viên dữ liệu lớp có thể được khởi tạo trực tiếp bởi hàm tạo ít tham số và được gán bởi hàm tạo tham số

7 hữu ích 2 bình luận chia sẻ

Xem nguồn: https://stackoverflow.com//questions/24232799/why-choose-struct-over-class

loading

loading