如何在Golang中编写简洁的代码
如何在Golang中编写简洁的代码 大家好。这个问题是关于如何编写整洁的代码。目前我正在尝试为我的国家制作一个新闻门户网站。我想从多个网站抓取数据来填充数据库。希望能帮助我规划一下代码的结构。我最近才开始用Go语言编程。所以任何帮助都会很有用。我目前的所有尝试都充斥着难以理解的硬编码。
func main() {
fmt.Println("hello world")
}
2 回复
问题是如何编写干净的代码
如何编写“干净的代码”是一个广泛的主题,没有明确的答案。我认为你需要更具体一些。这里有一个资源链接
我想为数据库解析多个网站
这也有点模糊。我曾作为一个学习项目做过一些“多Go托管”。我惊讶于你只需要很少的Go代码行。大部分内容是用HTML、CSS和Javascript编写的。https://hosting.go4webdev.org
更多关于如何在Golang中编写简洁的代码的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中编写简洁代码的关键是遵循标准库的惯用模式,并合理组织代码结构。对于新闻抓取项目,建议采用以下结构:
// 定义清晰的数据结构
type Article struct {
Title string `json:"title"`
Content string `json:"content"`
Source string `json:"source"`
Published time.Time `json:"published"`
URL string `json:"url"`
}
// 定义抓取器接口
type Fetcher interface {
Fetch() ([]Article, error)
}
// 具体网站抓取器实现
type BBCFetcher struct {
baseURL string
timeout time.Duration
}
func (f *BBCFetcher) Fetch() ([]Article, error) {
resp, err := http.Get(f.baseURL + "/news")
if err != nil {
return nil, fmt.Errorf("bbc fetch failed: %w", err)
}
defer resp.Body.Close()
// 解析逻辑
return f.parse(resp.Body)
}
func (f *BBCFetcher) parse(r io.Reader) ([]Article, error) {
// 具体的HTML解析实现
var articles []Article
// ... 解析逻辑
return articles, nil
}
// 数据库存储层
type Repository interface {
Save(articles []Article) error
GetLatest(count int) ([]Article, error)
}
type PostgresRepository struct {
db *sql.DB
}
func (r *PostgresRepository) Save(articles []Article) error {
tx, err := r.db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
stmt, err := tx.Prepare(`
INSERT INTO articles (title, content, source, published, url)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (url) DO NOTHING`)
if err != nil {
return err
}
defer stmt.Close()
for _, article := range articles {
_, err := stmt.Exec(
article.Title,
article.Content,
article.Source,
article.Published,
article.URL,
)
if err != nil {
return err
}
}
return tx.Commit()
}
// 主服务协调器
type NewsService struct {
fetchers []Fetcher
repo Repository
}
func (s *NewsService) Run(ctx context.Context) error {
var allArticles []Article
for _, fetcher := range s.fetchers {
articles, err := fetcher.Fetch()
if err != nil {
log.Printf("fetch error: %v", err)
continue
}
allArticles = append(allArticles, articles...)
}
if err := s.repo.Save(allArticles); err != nil {
return fmt.Errorf("save failed: %w", err)
}
return nil
}
// 配置驱动的初始化
func main() {
cfg := loadConfig()
db, err := sql.Open("postgres", cfg.DatabaseURL)
if err != nil {
log.Fatal(err)
}
defer db.Close()
service := &NewsService{
fetchers: []Fetcher{
&BBCFetcher{
baseURL: "https://www.bbc.com",
timeout: 30 * time.Second,
},
// 添加更多抓取器
},
repo: &PostgresRepository{db: db},
}
ctx := context.Background()
if err := service.Run(ctx); err != nil {
log.Fatal(err)
}
}
这个结构通过接口解耦了数据获取、存储和业务逻辑,每个组件职责单一,便于测试和维护。使用配置管理外部依赖,避免硬编码。错误处理采用Go的惯用方式,通过%w包装错误上下文。

