使用嵌入结构体的构造函数实例化结构体。

huangapple go评论66阅读模式
英文:

Instantiating struct using constructor of embedded struct

问题

我是一个Go的新手,正在尝试覆盖AWS Go SDK for DynamoDB中的一些方法。基本上,我想在DynamoDB客户端的某些方法中添加一些日志记录。我目前的代码如下:

type dynamoDBLogger struct {
  dynamodb.DynamoDB
}

func (d *dynamoDBLogger) DeleteItemWithContext(ctx context.Context, item *dynamodb.DeleteItemInput) (*dynamodb.DeleteItemOutput, error) {
    logger.Debug("Deleting from DynamoDB: %+v", *item)
    return d.DynamoDB.DeleteItemWithContext(ctx, item)
}

换句话说,它只是在实际调用之前添加了一个日志记录语句。这段代码可以编译通过。问题是现在我如何创建一个dynamoDBLogger的实例?唯一实例化DynamoDB的方法是使用dynamodb包中的一个方法:

func New(...) *dynamodb.DynamoDB

我能否以某种方式使用它来构建一个dynamoDBLogger的实例?不确定它是否会起作用,但我希望*dynamoDBLogger类型可以作为*dynamodb.DynamoDB使用。

编辑:我实际上注意到以下代码失败了:

func GetDynamoClient(sess *session.Session) *dynamodb.DynamoDB {
    svc := dynamoDBLogger{}
    svc.DynamoDB = *dynamodb.New(sess)
    return &svc
}

也就是说,类型系统不允许将*dynamodb.DynamoDB替换为*dynamoDBLogger。我想知道Go的类型系统是否允许我实现我想要的目标,因为dynamodb.DynamoDB不是一个接口。

英文:

I'm a Go newbie trying to override some methods in the AWS Go SDK for DynamoDB. Basically, I would like to add some logging to certain methods in the DynamoDB client. The code that I have is:

type dynamoDBLogger struct {
  dynamodb.DynamoDB
}

func (d *dynamoDBLogger) DeleteItemWithContext(ctx context.Context, item *dynamodb.DeleteItemInput) (*dynamodb.DeleteItemOutput, error) {
	logger.Debug("Deleting from DynamoDB: %+v", *item)
	return d.DynamoDB.DeleteItemWithContext(ctx, item)
}

In other words, it just adds a logging statement before the actual call. This code compiles. The problem is now how can I create a dynamoDBLogger? The only way to instantiate a DynamoDB is by using a method:

func New(...) *dynamodb.DynamoDB

in the dynamodb package. Can I somehow use that to build an instance of a dynamoDBLogger? Not sure if it'll work, but I would like for the *dynamoDbLogger type to be usable as a *dynamodb.DynamoDB.

EDIT: I actually noticed that the following fails:

func GetDynamoClient(sess *session.Session) *dynamodb.DynamoDB {
	svc := dynamoDBLogger{}
	svc.DynamoDB = *dynamodb.New(sess)
	return &svc
}

i.e. the type system doesn't allow substituting a *dynamodb.DynamoDB with a *dynamoDBLogger. I'm wondering if Go's type system allows what I'm trying to accomplish, since dynamodb.DynamoDB is not an interface?

答案1

得分: 1

更好的做法是使用 DynamoDB 接口。它提供了创建测试用例的模拟功能。示例代码如下:

package main

import (
	"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface"
)

type dynamoDBLogger struct {
	DynamoDBAPI
}

func NewDynamoDB() dynamodbiface.DynamoDBAPI {
	svc := &dynamoDBLogger{
		DynamoDBAPI: dynamodb.New(sess),
	}
	return &svc
}

// 在测试中

type mockDB struct {
	dynamodbiface.DynamoDBAPI
}

func NewMockDB() dynamodbiface.DynamoDBAPI {
}

在模拟中,你只需要实现程序中实际使用的方法。

完整示例请参考:https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbiface/

英文:

It is better to use dynamo db interface. It gives a possibility to create mocks for tests. Example:

package main

import (
	"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface"
)

type dynamoDBLogger struct {
	DynamoDBAPI
}

func NewDynamoDB() dynamodbiface.DynamoDBAPI {
	svc := &dynamoDBLogger{
		DynamoDBAPI: dynamodb.New(sess),
	}
	return &svc
}

// in tests

type mockDB struct {
	dynamodbiface.DynamoDBAPI
}

func NewMockDB() dynamodbiface.DynamoDBAPI {
}

In mock you need to implement the only methods that actually is used in the program.

Full example is on: https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbiface/

huangapple
  • 本文由 发表于 2022年1月17日 21:43:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/70742365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定