2 Câu hỏi: Làm thế nào để đảm bảo sự hiện diện của một trường cấu trúc như các giao diện làm cho các phương thức?

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Tôi có một số cấu trúc giao dịch:

SpendTx
NameTransferTx
NameUpdateTx
...

Tôi muốn ước tính kích thước của các cấu trúc này, ngoại trừ trường Phí. Tất cả đều có trường cấu trúc Phí. Hiện tại, đối với mỗi cấu trúc tôi có phương thức này:

func (tx *NameTransferTx) sizeEstimate() (int, error) {
    feeRlp, err := rlp.EncodeToBytes(tx.Fee)
    if err != nil {
        return 0, err
    }
    feeRlpLen := len(feeRlp)

    rlpRawMsg, err := tx.RLP()
    if err != nil {
        return 0, err
    }

    return len(rlpRawMsg) - feeRlpLen + 8, nil
}

Đó là rất nhiều mã trùng lặp, tất cả vì tôi không thể viết một cái gì đó như thế này:

type Tx interface {
    RLP() ([]byte, error)
    Fee utils.BigInt // Golang won't allow this
}
func estimateSizeOfTx(tx Tx) (int, error) {
    feeRlp, err := rlp.EncodeToBytes(tx.Fee)
    if err != nil {
        return 0, err
    }
    feeRlpLen := len(feeRlp)

    rlpRawMsg, err := tx.RLP()
    if err != nil {
        return 0, err
    }

    return len(rlpRawMsg) - feeRlpLen + 8, nil
}

Tất nhiên tôi có thể viết một hàm getter như getFee() và tạo một giao diện từ đó, nhưng điều đó không tốt hơn. Hay đó là cách người khác làm điều đó?

    
0
  1. Còn việc viết một cấu trúc với các trường phổ biến, như priceTx, sau đó nhúng nó vào các cấu trúc khác thì sao?
    2019-05-08 15: 58: 17Z
  2. Điều đó có thể thú vị - sẽ mất vài giờ để thử phương pháp này mặc dù.
    2019-05-08 21: 17: 32Z
2 Câu trả lời                              2                         

Bạn không. Nếu bạn không quan tâm đến loại cụ thể (nghĩa là, bạn có thể sử dụng giao diện), thì bạn không quan tâm đến dữ liệu, chỉ hành vi (đó là lý do tại sao giao diện chỉ xác định phương thức). Nếu bạn quan tâm đến dữ liệu, thì bạn đã hiểu sâu về nội bộ của loại và bạn nên sử dụng loại cụ thể cụ thể (hoặc sử dụng công tắc xác nhận /loại chuyển đổi để có được dữ liệu đó). Đây không phải là cụ thể; hầu hết các ngôn ngữ không cho phép chỉ định các trường trong giao diện.

Một getter sẽ không phải là điều tồi tệ nhất. Bạn cũng có thể gói gọn các trường bạn cần truy cập trực tiếp vào kiểu cấu trúc của riêng chúng và có một getter cho điều đó (nếu có nhiều trường liên quan bạn muốn làm việc cùng nhau). Cuối cùng, bạn có thể làm lại thiết kế tổng thể để loại bỏ hoặc di chuyển nhu cầu. Không có đủ ngữ cảnh để đưa ra một gợi ý khó khăn ở đây, nhưng để đoán tổng thể, có vẻ như bạn có thể có một cái gì đó ghi các giao dịch này đến một nơi nào đó, và đó là kích thước của những gì bạn nên viết. Vì có vẻ như bạn đang thực hiện tất cả quá trình xử lý liên quan để tạo thông điệp theo phương thức mà bạn đang cố gắng để có được độ dài cuối cùng của nó, bạn không thể tạo tin nhắn dưới dạng []byte, sử dụng độ dài của nó, sau đó sử dụng cùng một đầu ra khi bạn làm ... bất cứ điều gì bạn đang làm với những thứ này?

    
0
2019-05-08 16: 40: 49Z
  1. Tôi không chắc ý của bạn là gì "Vì có vẻ như bạn đang thực hiện tất cả quá trình xử lý liên quan để tạo tin nhắn theo phương thức mà bạn đang thử để có được độ dài cuối cùng của nó, bạn không thể tạo ra thông điệp dưới dạng byte [], lấy độ dài của nó và sau đó sử dụng cùng một đầu ra khi bạn làm ... bất cứ điều gì bạn đang làm với những điều này? " Đây chỉ là một bước trong một hoạt động lớn hơn - có một phương trình phức tạp phụ thuộc vào quy mô của giao dịch sau này.
    2019-05-08 20: 52: 18Z
  2. OK. Một lần nữa, thật khó để đoán các tùy chọn của bạn có thể là gì vì không có ngữ cảnh được cung cấp.
    2019-05-09 13: 20: 22Z

Ước tính kích thước của Tx yêu cầu Tx.RLP () (được bảo đảm bởi giao diện Tx) và trường Tx.Fee (luôn có sẵn nhưng không thể được chứng minh với trình biên dịch).

Ước tính kích thước là giống nhau cho tất cả các loại giao dịch. Vì vậy, tôi đã tìm thấy một giải pháp thỏa đáng làm cho việc ước tính kích thước trở thành một hàm riêng và tôi chỉ cung cấp Phí của giao dịch làm đối số cho hàm:

// sizeEstimate returns the size of the transaction when RLP serialized, assuming the Fee has a length of 8 bytes.
func calcSizeEstimate(tx Tx, fee *utils.BigInt) (int, error) {
    feeRlp, err := rlp.EncodeToBytes(fee)
    if err != nil {
        return 0, err
    }
    feeRlpLen := len(feeRlp)

    rlpRawMsg, err := tx.RLP()
    if err != nil {
        return 0, err
    }

    return len(rlpRawMsg) - feeRlpLen + 8, nil
}

...
func (tx *SpendTx) sizeEstimate() (int, error) {
    return calcSizeEstimate(tx, &tx.Fee)
}
...
func (tx *NamePreclaimTx) sizeEstimate() (int, error) {
    return calcSizeEstimate(tx, &tx.Fee)
}
...
func (tx *NameClaimTx) sizeEstimate() (int, error) {
    return calcSizeEstimate(tx, &tx.Fee)
}
...
    
0
2019-05-09 00: 15: 02Z
nguồn đặt đây